socialcast 1.2.3 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.travis.yml +1 -2
- data/bin/socialcast +2 -2
- data/lib/socialcast.rb +7 -15
- data/lib/socialcast/command_line/cli.rb +161 -0
- data/lib/socialcast/command_line/message.rb +18 -0
- data/lib/socialcast/command_line/provision.rb +330 -0
- data/lib/socialcast/command_line/version.rb +5 -0
- data/socialcast.gemspec +13 -10
- data/spec/fixtures/fake_attribute_map.rb +8 -6
- data/spec/fixtures/ldap_with_account_type_without_roles.yml +44 -0
- data/spec/fixtures/ldap_with_class_ldap_attribute.yml +47 -0
- data/spec/fixtures/ldap_with_connection_mapping.yml +52 -0
- data/spec/fixtures/ldap_with_connection_permission_mapping.yml +59 -0
- data/spec/fixtures/ldap_with_custom_attributes.yml +50 -0
- data/spec/fixtures/ldap_with_manager_attribute.yml +6 -3
- data/spec/fixtures/ldap_with_multiple_connection_mappings.yml +51 -0
- data/spec/fixtures/ldap_with_multiple_connection_permission_mappings.yml +75 -0
- data/spec/fixtures/ldap_with_plugin_mapping.yml +1 -1
- data/spec/fixtures/ldap_with_roles_without_account_type.yml +48 -0
- data/spec/fixtures/ldap_with_unique_identifier.yml +50 -0
- data/spec/fixtures/ldap_without_account_type_or_roles.yml +42 -0
- data/spec/{cli_spec.rb → socialcast/command_line/cli_spec.rb} +94 -82
- data/spec/socialcast/command_line/provision_spec.rb +497 -0
- data/spec/spec_helper.rb +2 -1
- metadata +103 -26
- data/lib/ext/array_ext.rb +0 -11
- data/lib/ext/string_ext.rb +0 -13
- data/lib/socialcast/cli.rb +0 -339
- data/lib/socialcast/message.rb +0 -17
- data/lib/socialcast/net_ldap_ext.rb +0 -87
- data/lib/socialcast/version.rb +0 -3
- 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.
|
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:
|
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
|
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
|
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:
|
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:
|
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
|
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
|
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/
|
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/
|
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
|
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/
|
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
data/lib/ext/string_ext.rb
DELETED
data/lib/socialcast/cli.rb
DELETED
@@ -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
|