socialcast 1.2.3 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +1 -2
  3. data/bin/socialcast +2 -2
  4. data/lib/socialcast.rb +7 -15
  5. data/lib/socialcast/command_line/cli.rb +161 -0
  6. data/lib/socialcast/command_line/message.rb +18 -0
  7. data/lib/socialcast/command_line/provision.rb +330 -0
  8. data/lib/socialcast/command_line/version.rb +5 -0
  9. data/socialcast.gemspec +13 -10
  10. data/spec/fixtures/fake_attribute_map.rb +8 -6
  11. data/spec/fixtures/ldap_with_account_type_without_roles.yml +44 -0
  12. data/spec/fixtures/ldap_with_class_ldap_attribute.yml +47 -0
  13. data/spec/fixtures/ldap_with_connection_mapping.yml +52 -0
  14. data/spec/fixtures/ldap_with_connection_permission_mapping.yml +59 -0
  15. data/spec/fixtures/ldap_with_custom_attributes.yml +50 -0
  16. data/spec/fixtures/ldap_with_manager_attribute.yml +6 -3
  17. data/spec/fixtures/ldap_with_multiple_connection_mappings.yml +51 -0
  18. data/spec/fixtures/ldap_with_multiple_connection_permission_mappings.yml +75 -0
  19. data/spec/fixtures/ldap_with_plugin_mapping.yml +1 -1
  20. data/spec/fixtures/ldap_with_roles_without_account_type.yml +48 -0
  21. data/spec/fixtures/ldap_with_unique_identifier.yml +50 -0
  22. data/spec/fixtures/ldap_without_account_type_or_roles.yml +42 -0
  23. data/spec/{cli_spec.rb → socialcast/command_line/cli_spec.rb} +94 -82
  24. data/spec/socialcast/command_line/provision_spec.rb +497 -0
  25. data/spec/spec_helper.rb +2 -1
  26. metadata +103 -26
  27. data/lib/ext/array_ext.rb +0 -11
  28. data/lib/ext/string_ext.rb +0 -13
  29. data/lib/socialcast/cli.rb +0 -339
  30. data/lib/socialcast/message.rb +0 -17
  31. data/lib/socialcast/net_ldap_ext.rb +0 -87
  32. data/lib/socialcast/version.rb +0 -3
  33. data/spec/net_ldap_ext_spec.rb +0 -107
data/spec/spec_helper.rb CHANGED
@@ -2,9 +2,10 @@ require 'rubygems'
2
2
  require 'bundler/setup'
3
3
  require 'webmock/rspec'
4
4
  require 'rspec/mocks'
5
+ require 'pry'
5
6
  RSpec::Mocks::setup(Object.new)
6
7
 
7
- require 'socialcast/cli'
8
+ require 'socialcast/command_line/cli'
8
9
 
9
10
  RSpec.configure do |config|
10
11
  config.mock_with :rspec
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.2.3
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Sonnek
@@ -10,26 +10,29 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-12-23 00:00:00.000000000 Z
13
+ date: 2014-03-18 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
18
  requirements:
19
- - - ! '>='
19
+ - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 1.4.0
21
+ version: '1.4'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
- - - ! '>='
26
+ - - ~>
27
27
  - !ruby/object:Gem::Version
28
- version: 1.4.0
28
+ version: '1.4'
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: json
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: '1.4'
33
36
  - - ! '>='
34
37
  - !ruby/object:Gem::Version
35
38
  version: 1.4.6
@@ -37,6 +40,9 @@ dependencies:
37
40
  prerelease: false
38
41
  version_requirements: !ruby/object:Gem::Requirement
39
42
  requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.4'
40
46
  - - ! '>='
41
47
  - !ruby/object:Gem::Version
42
48
  version: 1.4.6
@@ -44,6 +50,9 @@ dependencies:
44
50
  name: thor
45
51
  requirement: !ruby/object:Gem::Requirement
46
52
  requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: '0.14'
47
56
  - - ! '>='
48
57
  - !ruby/object:Gem::Version
49
58
  version: 0.14.6
@@ -51,6 +60,9 @@ dependencies:
51
60
  prerelease: false
52
61
  version_requirements: !ruby/object:Gem::Requirement
53
62
  requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: '0.14'
54
66
  - - ! '>='
55
67
  - !ruby/object:Gem::Version
56
68
  version: 0.14.6
@@ -58,6 +70,9 @@ dependencies:
58
70
  name: highline
59
71
  requirement: !ruby/object:Gem::Requirement
60
72
  requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '1.6'
61
76
  - - ! '>='
62
77
  - !ruby/object:Gem::Version
63
78
  version: 1.6.2
@@ -65,6 +80,9 @@ dependencies:
65
80
  prerelease: false
66
81
  version_requirements: !ruby/object:Gem::Requirement
67
82
  requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '1.6'
68
86
  - - ! '>='
69
87
  - !ruby/object:Gem::Version
70
88
  version: 1.6.2
@@ -72,6 +90,9 @@ dependencies:
72
90
  name: socialcast-net-ldap
73
91
  requirement: !ruby/object:Gem::Requirement
74
92
  requirements:
93
+ - - ~>
94
+ - !ruby/object:Gem::Version
95
+ version: '0.1'
75
96
  - - ! '>='
76
97
  - !ruby/object:Gem::Version
77
98
  version: 0.1.6
@@ -79,6 +100,9 @@ dependencies:
79
100
  prerelease: false
80
101
  version_requirements: !ruby/object:Gem::Requirement
81
102
  requirements:
103
+ - - ~>
104
+ - !ruby/object:Gem::Version
105
+ version: '0.1'
82
106
  - - ! '>='
83
107
  - !ruby/object:Gem::Version
84
108
  version: 0.1.6
@@ -86,34 +110,51 @@ dependencies:
86
110
  name: activeresource
87
111
  requirement: !ruby/object:Gem::Requirement
88
112
  requirements:
89
- - - ! '>='
113
+ - - ~>
90
114
  - !ruby/object:Gem::Version
91
- version: 2.3.11
115
+ version: '4.0'
92
116
  type: :runtime
93
117
  prerelease: false
94
118
  version_requirements: !ruby/object:Gem::Requirement
95
119
  requirements:
96
- - - ! '>='
120
+ - - ~>
121
+ - !ruby/object:Gem::Version
122
+ version: '4.0'
123
+ - !ruby/object:Gem::Dependency
124
+ name: activesupport
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ~>
128
+ - !ruby/object:Gem::Version
129
+ version: '4.0'
130
+ type: :runtime
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ~>
97
135
  - !ruby/object:Gem::Version
98
- version: 2.3.11
136
+ version: '4.0'
99
137
  - !ruby/object:Gem::Dependency
100
138
  name: rspec
101
139
  requirement: !ruby/object:Gem::Requirement
102
140
  requirements:
103
- - - ! '>='
141
+ - - ~>
104
142
  - !ruby/object:Gem::Version
105
- version: 2.11.0
143
+ version: '2.11'
106
144
  type: :development
107
145
  prerelease: false
108
146
  version_requirements: !ruby/object:Gem::Requirement
109
147
  requirements:
110
- - - ! '>='
148
+ - - ~>
111
149
  - !ruby/object:Gem::Version
112
- version: 2.11.0
150
+ version: '2.11'
113
151
  - !ruby/object:Gem::Dependency
114
152
  name: webmock
115
153
  requirement: !ruby/object:Gem::Requirement
116
154
  requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: '1.7'
117
158
  - - ! '>='
118
159
  - !ruby/object:Gem::Version
119
160
  version: 1.7.7
@@ -121,6 +162,9 @@ dependencies:
121
162
  prerelease: false
122
163
  version_requirements: !ruby/object:Gem::Requirement
123
164
  requirements:
165
+ - - ~>
166
+ - !ruby/object:Gem::Version
167
+ version: '1.7'
124
168
  - - ! '>='
125
169
  - !ruby/object:Gem::Version
126
170
  version: 1.7.7
@@ -138,6 +182,20 @@ dependencies:
138
182
  - - '='
139
183
  - !ruby/object:Gem::Version
140
184
  version: 0.9.2.2
185
+ - !ruby/object:Gem::Dependency
186
+ name: pry
187
+ requirement: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - ~>
190
+ - !ruby/object:Gem::Version
191
+ version: '0.9'
192
+ type: :development
193
+ prerelease: false
194
+ version_requirements: !ruby/object:Gem::Requirement
195
+ requirements:
196
+ - - ~>
197
+ - !ruby/object:Gem::Version
198
+ version: '0.9'
141
199
  description: publish messages to your stream from a command line interface
142
200
  email:
143
201
  - sean@socialcast.com
@@ -158,29 +216,38 @@ files:
158
216
  - Rakefile
159
217
  - bin/socialcast
160
218
  - config/ldap.yml
161
- - lib/ext/array_ext.rb
162
- - lib/ext/string_ext.rb
163
219
  - lib/socialcast.rb
164
- - lib/socialcast/cli.rb
165
- - lib/socialcast/message.rb
166
- - lib/socialcast/net_ldap_ext.rb
167
- - lib/socialcast/version.rb
220
+ - lib/socialcast/command_line/cli.rb
221
+ - lib/socialcast/command_line/message.rb
222
+ - lib/socialcast/command_line/provision.rb
223
+ - lib/socialcast/command_line/version.rb
168
224
  - socialcast.gemspec
169
- - spec/cli_spec.rb
170
225
  - spec/fixtures/credentials.yml
171
226
  - spec/fixtures/credentials_with_proxy.yml
172
227
  - spec/fixtures/fake_attribute_map.rb
173
228
  - spec/fixtures/ldap.yml
229
+ - spec/fixtures/ldap_with_account_type_without_roles.yml
174
230
  - spec/fixtures/ldap_with_array_permission_mapping.yml
231
+ - spec/fixtures/ldap_with_class_ldap_attribute.yml
232
+ - spec/fixtures/ldap_with_connection_mapping.yml
233
+ - spec/fixtures/ldap_with_connection_permission_mapping.yml
234
+ - spec/fixtures/ldap_with_custom_attributes.yml
175
235
  - spec/fixtures/ldap_with_interpolated_values.yml
176
236
  - spec/fixtures/ldap_with_manager_attribute.yml
237
+ - spec/fixtures/ldap_with_multiple_connection_mappings.yml
238
+ - spec/fixtures/ldap_with_multiple_connection_permission_mappings.yml
177
239
  - spec/fixtures/ldap_with_plugin_mapping.yml
178
240
  - spec/fixtures/ldap_with_profile_photo.yml
241
+ - spec/fixtures/ldap_with_roles_without_account_type.yml
242
+ - spec/fixtures/ldap_with_unique_identifier.yml
243
+ - spec/fixtures/ldap_without_account_type_or_roles.yml
179
244
  - spec/fixtures/ldap_without_permission_mappings.yml
180
- - spec/net_ldap_ext_spec.rb
245
+ - spec/socialcast/command_line/cli_spec.rb
246
+ - spec/socialcast/command_line/provision_spec.rb
181
247
  - spec/spec_helper.rb
182
248
  homepage: http://github.com/socialcast/socialcast-command-line
183
- licenses: []
249
+ licenses:
250
+ - MIT
184
251
  metadata: {}
185
252
  post_install_message:
186
253
  rdoc_options: []
@@ -198,21 +265,31 @@ required_rubygems_version: !ruby/object:Gem::Requirement
198
265
  version: '0'
199
266
  requirements: []
200
267
  rubyforge_project: socialcast
201
- rubygems_version: 2.1.7
268
+ rubygems_version: 2.2.1
202
269
  signing_key:
203
270
  specification_version: 4
204
271
  summary: command line interface to socialcast api
205
272
  test_files:
206
- - spec/cli_spec.rb
207
273
  - spec/fixtures/credentials.yml
208
274
  - spec/fixtures/credentials_with_proxy.yml
209
275
  - spec/fixtures/fake_attribute_map.rb
210
276
  - spec/fixtures/ldap.yml
277
+ - spec/fixtures/ldap_with_account_type_without_roles.yml
211
278
  - spec/fixtures/ldap_with_array_permission_mapping.yml
279
+ - spec/fixtures/ldap_with_class_ldap_attribute.yml
280
+ - spec/fixtures/ldap_with_connection_mapping.yml
281
+ - spec/fixtures/ldap_with_connection_permission_mapping.yml
282
+ - spec/fixtures/ldap_with_custom_attributes.yml
212
283
  - spec/fixtures/ldap_with_interpolated_values.yml
213
284
  - spec/fixtures/ldap_with_manager_attribute.yml
285
+ - spec/fixtures/ldap_with_multiple_connection_mappings.yml
286
+ - spec/fixtures/ldap_with_multiple_connection_permission_mappings.yml
214
287
  - spec/fixtures/ldap_with_plugin_mapping.yml
215
288
  - spec/fixtures/ldap_with_profile_photo.yml
289
+ - spec/fixtures/ldap_with_roles_without_account_type.yml
290
+ - spec/fixtures/ldap_with_unique_identifier.yml
291
+ - spec/fixtures/ldap_without_account_type_or_roles.yml
216
292
  - spec/fixtures/ldap_without_permission_mappings.yml
217
- - spec/net_ldap_ext_spec.rb
293
+ - spec/socialcast/command_line/cli_spec.rb
294
+ - spec/socialcast/command_line/provision_spec.rb
218
295
  - spec/spec_helper.rb
data/lib/ext/array_ext.rb DELETED
@@ -1,11 +0,0 @@
1
- class Array
2
- def self.wrap(object)
3
- if object.nil?
4
- []
5
- elsif object.respond_to?(:to_ary)
6
- object.to_ary
7
- else
8
- [object]
9
- end
10
- end
11
- end
@@ -1,13 +0,0 @@
1
- if RUBY_VERSION < '1.9.2'
2
- class String
3
- old_format = instance_method(:%)
4
-
5
- define_method(:%) do |arg|
6
- if arg.is_a?(Hash)
7
- self.gsub(/%\{(.*?)\}/) { arg[$1.to_sym] }
8
- else
9
- old_format.bind(self).call(arg)
10
- end
11
- end
12
- end
13
- end
@@ -1,339 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require 'rubygems'
4
-
5
- require "thor"
6
- require 'json'
7
- require 'rest_client'
8
- require 'highline'
9
- require 'net/ldap'
10
- require 'socialcast'
11
- require 'socialcast/message'
12
- require File.join(File.dirname(__FILE__), 'net_ldap_ext')
13
-
14
- require 'zlib'
15
- require 'logger'
16
- require 'builder'
17
- require 'set'
18
- require 'fileutils'
19
-
20
- # uncomment to debug HTTP traffic
21
- # class ActiveResource::Connection
22
- # def configure_http(http)
23
- # http = apply_ssl_options(http)
24
- # # Net::HTTP timeouts default to 60 seconds.
25
- # if @timeout
26
- # http.open_timeout = @timeout
27
- # http.read_timeout = @timeout
28
- # end
29
- # http.set_debug_output STDOUT
30
- # http
31
- # end
32
- # end
33
-
34
- module Socialcast
35
- class CLI < Thor
36
- include Thor::Actions
37
-
38
- method_option :trace, :type => :boolean, :aliases => '-v'
39
- def initialize(*args); super(*args) end
40
-
41
- desc "authenticate", "Authenticate using your Socialcast credentials"
42
- method_option :user, :type => :string, :aliases => '-u', :desc => 'email address for the authenticated user'
43
- method_option :password, :type => :string, :aliases => '-p', :desc => 'password for the authenticated user'
44
- method_option :domain, :type => :string, :default => 'api.socialcast.com', :desc => 'Socialcast community domain'
45
- method_option :proxy, :type => :string, :desc => 'HTTP proxy options for connecting to Socialcast server'
46
- def authenticate
47
- user = options[:user] || ask('Socialcast username: ')
48
- password = options[:password] || HighLine.new.ask("Socialcast password: ") { |q| q.echo = false }.to_s
49
- domain = options[:domain]
50
-
51
- url = ['https://', domain, '/api/authentication'].join
52
- say "Authenticating #{user} to #{url}"
53
- params = {:email => user, :password => password }
54
- RestClient.log = Logger.new(STDOUT) if options[:trace]
55
- RestClient.proxy = options[:proxy] if options[:proxy]
56
- resource = RestClient::Resource.new url
57
- response = resource.post params, :accept => :json
58
- say "API response: #{response.body.to_s}" if options[:trace]
59
- communities = JSON.parse(response.body.to_s)['communities']
60
- domain = communities.detect {|c| c['domain'] == domain} ? domain : communities.first['domain']
61
-
62
- Socialcast.credentials = {:user => user, :password => password, :domain => domain, :proxy => options[:proxy]}
63
- say "Authentication successful for #{domain}"
64
- end
65
-
66
- desc "share MESSAGE", "Posts a new message into socialcast"
67
- method_option :url, :type => :string, :desc => '(optional) url to associate to the message'
68
- method_option :message_type, :type => :string, :desc => '(optional) force an alternate message_type'
69
- method_option :attachments, :type => :array, :default => []
70
- method_option :group_id, :type => :numeric, :desc => "(optional) ID of group to post into"
71
- def share(message = nil)
72
- message ||= $stdin.read_nonblock(100_000) rescue nil
73
-
74
- attachment_ids = []
75
- options[:attachments].each do |path|
76
- Dir[File.expand_path(path)].each do |attachment|
77
- say "Uploading attachment #{attachment}..."
78
- uploader = Socialcast.resource_for_path '/api/attachments', {}, options[:trace]
79
- uploader.post({:attachment => File.new(attachment)}, {:accept => :json}) do |response, request, result|
80
- if response.code == 201
81
- attachment_ids << JSON.parse(response.body)['attachment']['id']
82
- else
83
- say "Error uploading attachment: #{response.body}"
84
- end
85
- end
86
- end
87
- end
88
-
89
- ActiveResource::Base.logger = Logger.new(STDOUT) if options[:trace]
90
- Socialcast::Message.configure_from_credentials
91
- Socialcast::Message.create :body => message, :url => options[:url], :message_type => options[:message_type], :attachment_ids => attachment_ids, :group_id => options[:group_id]
92
-
93
- say "Message has been shared"
94
- end
95
-
96
- desc 'provision', 'provision users from ldap compatible user repository'
97
- method_option :config, :default => 'ldap.yml', :aliases => '-c'
98
- method_option :output, :default => 'users.xml.gz', :aliases => '-o'
99
- method_option :setup, :type => :boolean
100
- method_option :delete_users_file, :type => :boolean
101
- method_option :test, :type => :boolean
102
- method_option :skip_emails, :type => :boolean
103
- method_option :force, :type => :boolean, :aliases => '-f', :default => false
104
- method_option :sanity_check, :type => :boolean, :default => false
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."
106
- def provision
107
- config = ldap_config options
108
- load_plugins options
109
-
110
- http_config = config.fetch 'http', {}
111
- mappings = config.fetch 'mappings', {}
112
- permission_mappings = config.fetch 'permission_mappings', {}
113
-
114
- user_identifier_list = %w{email unique_identifier employee_number}
115
- user_whitelist = Set.new
116
- output_file = File.join Dir.pwd, options[:output]
117
-
118
- Zlib::GzipWriter.open(output_file) do |gz|
119
- xml = Builder::XmlMarkup.new(:target => gz, :indent => 1)
120
- xml.instruct!
121
- xml.export do |export|
122
- export.users(:type => "array") do |users|
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]) }
128
- end # connections
129
- end # users
130
- end # export
131
- end # gzip
132
-
133
- if options[:sanity_check]
134
- say "Sanity checking users currently marked as needing to be terminated"
135
- ldap_connections(config) do |key, connection, ldap|
136
- (current_socialcast_users(http_config) - user_whitelist).each do |user_identifiers|
137
- combined_filters = []
138
- user_identifier_list.each_with_index do |identifier, index|
139
- combined_filters << ((mappings[identifier].blank? || user_identifiers[index].nil?) ? nil : Net::LDAP::Filter.eq(mappings[identifier], user_identifiers[index]))
140
- end
141
- combined_filters.compact!
142
- filter = ((combined_filters.size > 1) ? '(|%s)' : '%s') % combined_filters.join(' ')
143
- filter = Net::LDAP::Filter.construct(filter) & Net::LDAP::Filter.construct(connection["filter"])
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?
146
- end
147
- end
148
- end
149
-
150
- if user_whitelist.empty? && !options[:force]
151
- Kernel.abort("Skipping upload to Socialcast since no users were found")
152
- else
153
- say "Uploading dataset to Socialcast..."
154
- resource = Socialcast.resource_for_path '/api/users/provision', http_config
155
- begin
156
- File.open(output_file, 'r') do |file|
157
- request_params = {:file => file}
158
- request_params[:skip_emails] = 'true' if (config['options']["skip_emails"] || options[:skip_emails])
159
- request_params[:test] = 'true' if (config['options']["test"] || options[:test])
160
- resource.post request_params, :accept => :json
161
- end
162
- rescue RestClient::Unauthorized => e
163
- Kernel.abort "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
164
- end
165
- say "Finished"
166
- end
167
- File.delete(output_file) if (config['options']['delete_users_file'] || options[:delete_users_file])
168
- end
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
-
217
- no_tasks do
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
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
-
298
- def ldap_connections(config)
299
- config["connections"].each_pair do |key, connection|
300
- say "Connecting to #{key} at #{[connection["host"], connection["port"]].join(':')}"
301
- ldap = create_ldap_instance(connection)
302
- say "Searching base DN: #{connection["basedn"]} with filter: #{connection["filter"]}"
303
- yield key, connection, ldap
304
- end
305
- end
306
-
307
- def create_ldap_instance(connection)
308
- ldap = Net::LDAP.new :host => connection["host"], :port => connection["port"], :base => connection["basedn"]
309
- ldap.encryption connection['encryption'].to_sym if connection['encryption']
310
- ldap.auth connection["username"], connection["password"]
311
- ldap
312
- end
313
-
314
- def current_socialcast_users(http_config)
315
- current_socialcast_list = Set.new
316
- request_params = {:per_page => 500}
317
- request_params[:page] = 1
318
- resource = create_socialcast_user_index_request(http_config, request_params)
319
- while true
320
- response = resource.get :accept => :json
321
- result = JSON.parse(response)
322
- users = result["users"]
323
- break if users.blank?
324
- request_params[:page] += 1
325
- resource = create_socialcast_user_index_request(http_config, request_params)
326
- users.each do |user|
327
- current_socialcast_list << [user['contact_info']['email'], user['company_login'], user['employee_number']]
328
- end
329
- end
330
- current_socialcast_list
331
- end
332
-
333
- def create_socialcast_user_index_request(http_config, request_params)
334
- path_template = "/api/users?per_page=%{per_page}&page=%{page}"
335
- Socialcast.resource_for_path((path_template % request_params), http_config)
336
- end
337
- end
338
- end
339
- end