socialcast 1.3.11 → 1.3.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a6def41c8c9fc333d5375b7e0ad9b403594663dd
4
- data.tar.gz: 70370fc44d5b564bb69911a6b1919811bbf95b9f
3
+ metadata.gz: 610338f9bd0ce308510f29fe684fc4ed7f876fd4
4
+ data.tar.gz: 67eadbc1549337bbc9c0bafeaa4f934c8f9d1d70
5
5
  SHA512:
6
- metadata.gz: 22d41b04fa02c612b5a4486a7f7c1898bda5647e690a5054bb28e42e0438613f3b0acb6478b5ec668cce3daf37e9f9f7a9278d2eb0a506b9e1cddb9880290020
7
- data.tar.gz: a2738fb5abcfefe29222c4dd85dca607f114f99ff08cc89073205210dcc616caf8f395061191ddafd36c1b4ea6da4fc7210407bdb9734f6bba82014bfe8e2c81
6
+ metadata.gz: bbc659eefaace5269780c1052706eb9fe860f3e585bff2d23353b58924c331533e1005eb11d1546b98b5a30b403fd6e5593f943bf4b0da958c07247ec308692b
7
+ data.tar.gz: c85326a13ca5c7c637e70b474497a1827c05a9f5f370859b29eb311f52f171e922ca7c01161670f84d895be36d3800662eb32bbe20ecaed017ec78b25c56c4f4
@@ -5,6 +5,8 @@ require 'active_support/core_ext/array/wrap'
5
5
  module Socialcast
6
6
  module CommandLine
7
7
  class LDAPConnector
8
+ class ConcurrentSearchError < StandardError; end
9
+
8
10
  UNIQUE_IDENTIFIER_ATTRIBUTE = "unique_identifier"
9
11
  EMAIL_ATTRIBUTE = "email"
10
12
  MANAGER_ATTRIBUTE = "manager"
@@ -14,66 +16,65 @@ module Socialcast
14
16
 
15
17
  attr_reader :attribute_mappings, :connection_name
16
18
 
17
- def self.with_connector(connection_name, config)
18
- connection_config = config["connections"][connection_name]
19
- ldap = Net::LDAP.new(:host => connection_config["host"], :port => connection_config["port"], :base => connection_config["basedn"]).tap do |ldap_instance|
20
- ldap_instance.encryption connection_config['encryption'].to_sym if connection_config['encryption']
21
- ldap_instance.auth connection_config["username"], connection_config["password"]
22
- end
23
-
24
- ldap.open do |connected_ldap_instance|
25
- yield new(connection_name, config, connected_ldap_instance)
26
- end
27
- end
28
-
29
19
  def self.attribute_mappings_for(connection_name, config)
30
20
  config['connections'][connection_name]['mappings'] || config.fetch('mappings', {})
31
21
  end
32
22
 
33
- def initialize(connection_name, config, ldap)
23
+ def initialize(connection_name, config)
34
24
  @connection_name = connection_name
35
25
  @config = config
36
- @ldap = ldap
37
- @group_unique_identifiers = fetch_group_unique_identifiers
38
- @dn_to_email_hash = fetch_dn_to_email_hash
39
26
  end
40
27
 
41
28
  def each_user_hash
42
- each_ldap_entry(ldap_user_search_attributes) do |entry|
43
- yield build_user_hash_from_mappings(entry)
29
+ ldap.open do
30
+ fetch_group_unique_identifiers
31
+ fetch_dn_to_email_hash
32
+
33
+ each_ldap_entry(ldap_user_search_attributes) do |entry|
34
+ yield build_user_hash_from_mappings(entry)
35
+ end
44
36
  end
45
37
  end
46
38
 
47
39
  def each_photo_hash
48
- each_ldap_entry(ldap_photo_search_attributes) do |entry|
49
- photo_hash = build_photo_hash_from_mappings(entry)
50
- yield photo_hash if photo_hash.present?
40
+ ldap.open do
41
+ each_ldap_entry(ldap_photo_search_attributes) do |entry|
42
+ photo_hash = build_photo_hash_from_mappings(entry)
43
+ yield photo_hash if photo_hash.present?
44
+ end
51
45
  end
52
46
  end
53
47
 
54
48
  def fetch_user_hash(identifier, options)
55
- options = options.dup
56
- identifying_field = options.delete(:identifying_field) || UNIQUE_IDENTIFIER_ATTRIBUTE
49
+ ldap.open do
50
+ fetch_group_unique_identifiers
51
+ fetch_dn_to_email_hash
57
52
 
58
- filter = if connection_config['filter'].present?
59
- Net::LDAP::Filter.construct(connection_config['filter'])
60
- else
61
- Net::LDAP::Filter.pres("objectclass")
62
- end
53
+ options = options.dup
54
+ identifying_field = options.delete(:identifying_field) || UNIQUE_IDENTIFIER_ATTRIBUTE
63
55
 
64
- filter = filter & Net::LDAP::Filter.construct("#{attribute_mappings[identifying_field]}=#{identifier}")
56
+ filter = if connection_config['filter'].present?
57
+ Net::LDAP::Filter.construct(connection_config['filter'])
58
+ else
59
+ Net::LDAP::Filter.pres("objectclass")
60
+ end
65
61
 
66
- search(:base => connection_config['basedn'], :filter => filter, :attributes => ldap_user_search_attributes, :size => 1) do |entry|
67
- return build_user_hash_from_mappings(entry)
68
- end
62
+ filter = filter & Net::LDAP::Filter.construct("#{attribute_mappings[identifying_field]}=#{identifier}")
69
63
 
70
- nil
64
+ search(:base => connection_config['basedn'], :filter => filter, :attributes => ldap_user_search_attributes, :size => 1) do |entry|
65
+ return build_user_hash_from_mappings(entry)
66
+ end
67
+
68
+ nil
69
+ end
71
70
  end
72
71
 
73
72
  def attribute_mappings
74
73
  @attribute_mappings ||= LDAPConnector.attribute_mappings_for(@connection_name, @config)
75
74
  end
76
75
 
76
+ private
77
+
77
78
  # grab a *single* value of an attribute
78
79
  # abstracts away ldap multivalue attributes
79
80
  def grab(entry, attribute)
@@ -99,7 +100,16 @@ module Socialcast
99
100
  end
100
101
  end
101
102
 
102
- private
103
+ def ldap
104
+ @ldap ||= Net::LDAP.new(:host => connection_config["host"], :port => connection_config["port"], :base => connection_config["basedn"]).tap do |ldap_instance|
105
+ ldap_instance.encryption connection_config['encryption'].to_sym if connection_config['encryption']
106
+ ldap_instance.auth connection_config["username"], connection_config["password"]
107
+ end
108
+ end
109
+
110
+ def root_namingcontexts
111
+ @root_naming_contexts ||= Array.wrap(@ldap.search_root_dse.namingcontexts)
112
+ end
103
113
 
104
114
  def each_ldap_entry(attributes)
105
115
  search(:return_result => false, :filter => connection_config["filter"], :base => connection_config["basedn"], :attributes => attributes) do |entry|
@@ -156,17 +166,24 @@ module Socialcast
156
166
  end
157
167
 
158
168
  def search(search_options)
159
- options_for_search = if search_options[:base].present?
160
- Array.wrap(search_options)
161
- else
162
- distinguished_names = Array.wrap(@ldap.search_root_dse.namingcontexts)
163
- options_for_search = distinguished_names.map { |dn| search_options.merge(:base => dn ) }
164
- end
165
-
166
- options_for_search.each do |options|
167
- @ldap.search(options) do |entry|
168
- yield(entry)
169
+ raise ConcurrentSearchError.new "Cannot perform concurrent searches on an open ldap connection" if @search_in_progress
170
+ begin
171
+ options_for_search = if search_options[:base].present?
172
+ Array.wrap(search_options)
173
+ else
174
+ options_for_search = root_namingcontexts.map { |dn| search_options.merge(:base => dn ) }
175
+ end
176
+
177
+ options_for_search.each do |options|
178
+ @search_in_progress = true
179
+
180
+ @ldap.search(options) do |entry|
181
+ yield(entry)
182
+ end
183
+
169
184
  end
185
+ ensure
186
+ @search_in_progress = false
170
187
  end
171
188
  end
172
189
 
@@ -190,30 +207,34 @@ module Socialcast
190
207
  end
191
208
 
192
209
  def fetch_group_unique_identifiers
193
- return nil unless group_membership_mappings.present?
194
-
195
- {}.tap do |groups|
196
- search_options = {
197
- :return_result => false,
198
- :filter => group_membership_mappings["filter"],
199
- :base => connection_config["basedn"],
200
- :attributes => [group_membership_mappings[UNIQUE_IDENTIFIER_ATTRIBUTE]]
201
- }
202
-
203
- search(search_options) do |entry|
204
- groups[grab(entry, "dn")] = grab(entry, group_membership_mappings[UNIQUE_IDENTIFIER_ATTRIBUTE])
205
- end
206
- end
210
+ @group_unique_identifiers ||= if group_membership_mappings.present?
211
+ {}.tap do |groups|
212
+ search_options = {
213
+ :return_result => false,
214
+ :filter => group_membership_mappings["filter"],
215
+ :base => connection_config["basedn"],
216
+ :attributes => [group_membership_mappings[UNIQUE_IDENTIFIER_ATTRIBUTE]]
217
+ }
218
+
219
+ search(search_options) do |entry|
220
+ groups[grab(entry, "dn")] = grab(entry, group_membership_mappings[UNIQUE_IDENTIFIER_ATTRIBUTE])
221
+ end
222
+ end
223
+ else
224
+ {}
225
+ end
207
226
  end
208
227
 
209
228
  def fetch_dn_to_email_hash
210
- return nil unless attribute_mappings[MANAGER_ATTRIBUTE].present?
211
-
212
- {}.tap do |dn_to_email_hash|
213
- each_ldap_entry(ldap_mail_search_attributes) do |entry|
214
- dn_to_email_hash[entry.dn] = grab(entry, attribute_mappings[EMAIL_ATTRIBUTE])
215
- end
216
- end
229
+ @dn_to_email_hash ||= if attribute_mappings[MANAGER_ATTRIBUTE].present?
230
+ {}.tap do |dn_to_email_hash|
231
+ each_ldap_entry(ldap_mail_search_attributes) do |entry|
232
+ dn_to_email_hash[entry.dn] = grab(entry, attribute_mappings[EMAIL_ATTRIBUTE])
233
+ end
234
+ end
235
+ else
236
+ {}
237
+ end
217
238
  end
218
239
 
219
240
  def add_primary_attributes(entry, user_hash)
@@ -18,11 +18,15 @@ module Socialcast
18
18
  @http_config ||= @ldap_config.fetch 'http', {}
19
19
  end
20
20
 
21
+ def ldap_connectors
22
+ @ldap_connectors ||= @ldap_config['connections'].map do |connection_name, _|
23
+ LDAPConnector.new(connection_name, @ldap_config)
24
+ end
25
+ end
26
+
21
27
  def each_ldap_connector
22
- @ldap_config['connections'].keys.each do |connection_name|
23
- LDAPConnector.with_connector(connection_name, @ldap_config) do |ldap_connector|
24
- yield ldap_connector
25
- end
28
+ ldap_connectors.each do |ldap_connector|
29
+ yield ldap_connector
26
30
  end
27
31
  end
28
32
 
@@ -1,5 +1,5 @@
1
1
  module Socialcast
2
2
  module CommandLine
3
- VERSION = "1.3.11"
3
+ VERSION = "1.3.12"
4
4
  end
5
5
  end
@@ -21,7 +21,7 @@ describe Socialcast::CommandLine::CLI do
21
21
 
22
22
  let(:ldap) do
23
23
  ldap_instance = double(Net::LDAP, :auth => nil, :encryption => nil)
24
- ldap_instance.should_receive(:open).and_yield(ldap_instance)
24
+ ldap_instance.should_receive(:open).and_yield
25
25
  Net::LDAP.should_receive(:new).and_return(ldap_instance)
26
26
  ldap_instance
27
27
  end
@@ -49,6 +49,7 @@ describe Socialcast::CommandLine::LDAPConnector do
49
49
  let(:ldap) { double(Net::LDAP, :open => nil, :encryption => nil, :auth => nil) }
50
50
 
51
51
  before do
52
+ ldap.stub(:open).and_yield
52
53
  Net::LDAP.stub(:new).and_return(ldap)
53
54
  end
54
55
 
@@ -62,7 +63,7 @@ describe Socialcast::CommandLine::LDAPConnector do
62
63
 
63
64
  describe "#each_user_hash" do
64
65
  context "when the entry has an email" do
65
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
66
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
66
67
  let(:entry) { create_entry('user', :mail => 'user@example.com', :givenName => 'first name', :sn => 'last name') }
67
68
  before do
68
69
  ldap.should_receive(:search).once.with(hash_including(:attributes => ['givenName', 'sn', 'mail', 'isMemberOf'])).and_yield(entry)
@@ -84,7 +85,7 @@ describe Socialcast::CommandLine::LDAPConnector do
84
85
  end
85
86
 
86
87
  context("when the entry does not have a unique_identifier or email") do
87
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
88
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
88
89
  let(:entry) { create_entry('user', :mail => nil, :givenName => 'first name', :sn => 'last name') }
89
90
  before do
90
91
  ldap.should_receive(:search).once.with(hash_including(:attributes => ['givenName', 'sn', 'mail', 'isMemberOf'])).and_yield(entry)
@@ -104,7 +105,7 @@ describe Socialcast::CommandLine::LDAPConnector do
104
105
  "unique_identifier" => "uid"
105
106
  }
106
107
  end
107
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
108
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
108
109
  let(:entry) { create_entry('user', :uid => 'unique identifier', :givenName => 'first name', :sn => 'last name') }
109
110
  before do
110
111
  ldap.should_receive(:search).once.with(hash_including(:attributes => ['givenName', 'sn', 'uid', 'isMemberOf'])).and_yield(entry)
@@ -125,7 +126,7 @@ describe Socialcast::CommandLine::LDAPConnector do
125
126
  end
126
127
 
127
128
  context "when the entry has a profile photo" do
128
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
129
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
129
130
  let(:entry) { create_entry('user', :mail => 'user@example.com', :givenName => 'first name', :sn => 'last name') }
130
131
  let(:mappings) do
131
132
  {
@@ -155,7 +156,7 @@ describe Socialcast::CommandLine::LDAPConnector do
155
156
  end
156
157
 
157
158
  context "when the entry has a manager" do
158
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
159
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
159
160
  let(:employee_entry) { create_entry('user', :mail => 'user@example.com', :givenName => 'first name', :sn => 'last name', :manager_dn => 'cn=manager,dc=example,dc=com') }
160
161
  let(:manager_entry) { create_entry('manager', :mail => 'manager@example.com', :givenName => 'manager first name', :sn => 'manager last name') }
161
162
  let(:employee_mail_entry) { create_entry('user', :mail => 'user@example.com') }
@@ -212,7 +213,7 @@ describe Socialcast::CommandLine::LDAPConnector do
212
213
  end
213
214
 
214
215
  context "with multiple manager entries" do
215
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
216
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
216
217
  let(:employee_entry1) { create_entry('user1', :mail => 'user1@example.com', :givenName => 'first name1', :sn => 'last name1', :manager_dn => 'cn=manager1,dc=example,dc=com') }
217
218
  let(:employee_entry2) { create_entry('user2', :mail => 'user2@example.com', :givenName => 'first name2', :sn => 'last name2', :manager_dn => 'cn=manager2,dc=example,dc=com') }
218
219
  let(:employee_entry3) { create_entry('user3', :mail => 'user3@example.com', :givenName => 'first name3', :sn => 'last name3', :manager_dn => 'cn=manager1,dc=example,dc=com') }
@@ -324,7 +325,7 @@ describe Socialcast::CommandLine::LDAPConnector do
324
325
  end
325
326
 
326
327
  context "with attribute mappings at the connection level" do
327
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
328
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
328
329
  before do
329
330
  connection.merge!({ "mappings" => { "email" => "mailConnection" } })
330
331
  entry = create_entry 'user', :mailConnection => 'user@example.com'
@@ -344,7 +345,7 @@ describe Socialcast::CommandLine::LDAPConnector do
344
345
  end
345
346
  end
346
347
  context "with permission mappings at the connection level" do
347
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
348
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
348
349
  let(:ldap_groups) { ["cn=External,dc=example,dc=com", "cn=BizAdmins,dc=example,dc=com", "cn=TownHallAdmins,dc=example,dc=com"] }
349
350
  before do
350
351
  connection.merge!({
@@ -379,7 +380,7 @@ describe Socialcast::CommandLine::LDAPConnector do
379
380
  end
380
381
  end
381
382
  context "with external ldap group memberships" do
382
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
383
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
383
384
  let(:entry) do
384
385
  create_entry('user', :mail => 'user@example.com',
385
386
  :givenName => 'first name',
@@ -404,7 +405,7 @@ describe Socialcast::CommandLine::LDAPConnector do
404
405
  end
405
406
  end
406
407
  context "with role ldap group memberships" do
407
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
408
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
408
409
  let(:entry) do
409
410
  create_entry('user', :mail => 'user@example.com',
410
411
  :givenName => 'first name',
@@ -436,7 +437,7 @@ describe Socialcast::CommandLine::LDAPConnector do
436
437
  "unique_identifier" => "gid"
437
438
  }
438
439
  end
439
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
440
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
440
441
  let(:group_entry1) do
441
442
  create_entry('group1', :dn => "cn=Sales,dc=example,dc=com", :gid => "sales_group_id")
442
443
  end
@@ -481,11 +482,49 @@ describe Socialcast::CommandLine::LDAPConnector do
481
482
  }))
482
483
  end
483
484
  end
485
+
486
+ context "calling when a search is already being performed" do
487
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
488
+ before do
489
+ ldap.should_receive(:search).and_yield(create_entry('user', :mail => 'user@example.com'))
490
+ end
491
+ it "raises an error" do
492
+ expect do
493
+ connector.each_user_hash do |user_hash|
494
+ connector.each_user_hash do |another_user_hash|
495
+ # connection already open
496
+ end
497
+ end
498
+ end.to raise_error Socialcast::CommandLine::LDAPConnector::ConcurrentSearchError
499
+ end
500
+ end
501
+
502
+ context "calling when a search is already being performed, rescuing, then calling again" do
503
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
504
+ before do
505
+ ldap.should_receive(:search).and_yield(create_entry('user', :mail => 'user@example.com'))
506
+ end
507
+ it "raises an error" do
508
+ expect do
509
+ connector.each_user_hash do |user_hash|
510
+ begin
511
+ connector.each_user_hash do |another_user_hash|
512
+ # connection already open
513
+ end
514
+ rescue Socialcast::CommandLine::LDAPConnector::ConcurrentSearchError
515
+ end
516
+ connector.each_user_hash do |another_user_hash|
517
+ # connection already open
518
+ end
519
+ end
520
+ end.to raise_error Socialcast::CommandLine::LDAPConnector::ConcurrentSearchError
521
+ end
522
+ end
484
523
  end
485
524
 
486
525
  describe "#each_photo_hash" do
487
526
  context "when the entry has an email and photo" do
488
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
527
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
489
528
  let(:entry) { create_entry('user', :mail => 'user@example.com', :jpegPhoto => "photo") }
490
529
  let(:mappings) do
491
530
  {
@@ -508,7 +547,7 @@ describe Socialcast::CommandLine::LDAPConnector do
508
547
  end
509
548
  end
510
549
  context "when the entry does not have an email" do
511
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
550
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
512
551
  let(:entry) { create_entry('user', :mail => '', :jpegPhoto => "photo") }
513
552
  let(:mappings) do
514
553
  {
@@ -530,7 +569,7 @@ describe Socialcast::CommandLine::LDAPConnector do
530
569
  end
531
570
 
532
571
  context "when the entry does not have a photo" do
533
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
572
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
534
573
  let(:entry) { create_entry('user', :mail => 'user@example.com', :jpegPhoto => "") }
535
574
  let(:mappings) do
536
575
  {
@@ -552,7 +591,7 @@ describe Socialcast::CommandLine::LDAPConnector do
552
591
  end
553
592
 
554
593
  context "when the entry has a binary photo with incorrect encoding" do
555
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
594
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
556
595
  let(:entry) { create_entry('user', :mail => 'user@example.com', :jpegPhoto => "\x89PNGabc") }
557
596
  let(:mappings) do
558
597
  {
@@ -585,7 +624,7 @@ describe Socialcast::CommandLine::LDAPConnector do
585
624
  "unique_identifier" => "uid"
586
625
  }
587
626
  end
588
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
627
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
589
628
  let(:entry) { create_entry 'user', :uid => 'unique identifier', :givenName => 'first name', :sn => 'last name' }
590
629
  before do
591
630
  filter = Net::LDAP::Filter.construct('(&(mail=*)(uid=unique identifier))')
@@ -605,8 +644,9 @@ describe Socialcast::CommandLine::LDAPConnector do
605
644
  }
606
645
  end
607
646
  end
647
+
608
648
  context "specifying an identifying field" do
609
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
649
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
610
650
  let(:entry) { create_entry 'user', :mail => 'user@example.com', :givenName => 'first name', :sn => 'last name' }
611
651
  before do
612
652
  filter = Net::LDAP::Filter.construct('(&(mail=*)(mail=user@example.com))')
@@ -630,7 +670,7 @@ describe Socialcast::CommandLine::LDAPConnector do
630
670
 
631
671
  context "without a filter specified" do
632
672
  let(:filter) { "" }
633
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
673
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
634
674
  let(:entry) { create_entry 'user', :mail => 'user@example.com', :givenName => 'first name', :sn => 'last name' }
635
675
  before do
636
676
  filter = Net::LDAP::Filter.construct('(&(objectclass=*)(mail=user@example.com))')
@@ -651,6 +691,76 @@ describe Socialcast::CommandLine::LDAPConnector do
651
691
  }
652
692
  end
653
693
  end
694
+
695
+ context "calling more than once with managers and groups configured" do
696
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
697
+ let(:manager) { create_entry('manager', :mail => 'manager@example.com', :givenName => 'manager first name', :sn => 'manager last name') }
698
+ let(:user1) { create_entry 'user1', :mail => 'user1@example.com', :givenName => 'first name 1', :sn => 'last name 1', :isMemberOf => [] }
699
+ let(:user2) { create_entry 'user2', :mail => 'user2@example.com', :givenName => 'first name 2', :sn => 'last name 2', :isMemberOf => ["cn=Sales,dc=example,dc=com"] }
700
+ let(:group) { create_entry('group', :dn => "cn=Sales,dc=example,dc=com", :gid => "sales_group_id") }
701
+ let(:mappings) do
702
+ {
703
+ "first_name" => "givenName",
704
+ "last_name" => "sn",
705
+ "email" => "mail",
706
+ "manager" => "manager_dn"
707
+ }
708
+ end
709
+ let(:group_membership_mappings) do
710
+ {
711
+ "filter" => "(objectClass=groupOfUniqueNames)",
712
+ "unique_identifier" => "gid"
713
+ }
714
+ end
715
+ before do
716
+ ldap.should_receive(:search).once.ordered.with(
717
+ :return_result => false,
718
+ :filter => "(objectClass=groupOfUniqueNames)",
719
+ :base => "dc=example,dc=com",
720
+ :attributes => ["gid"]).and_yield(group)
721
+
722
+ ldap.should_receive(:search).once.ordered.with(
723
+ :return_result => false,
724
+ :filter => "(mail=*)",
725
+ :base => "dc=example,dc=com",
726
+ :attributes => ["mail"]).and_yield(manager)
727
+
728
+ filter1 = Net::LDAP::Filter.construct('(&(mail=*)(mail=user1@example.com))')
729
+ ldap.should_receive(:search).once.ordered
730
+ .with(hash_including(:attributes => ['givenName', 'sn', 'mail', 'manager_dn', 'isMemberOf'], :filter => filter1))
731
+ .and_yield(user1)
732
+
733
+ filter2 = Net::LDAP::Filter.construct('(&(mail=*)(mail=user2@example.com))')
734
+ ldap.should_receive(:search).once.ordered
735
+ .with(hash_including(:attributes => ['givenName', 'sn', 'mail', 'manager_dn', 'isMemberOf'], :filter => filter2))
736
+ .and_yield(user2)
737
+ end
738
+ it "caches managers and groups" do
739
+ connector.fetch_user_hash('user1@example.com', :identifying_field => 'email').should == {
740
+ 'account_type' => 'member',
741
+ 'contact_info' => {
742
+ 'email' => 'user1@example.com'
743
+ },
744
+ 'custom_fields' => [{ 'id' => 'manager_email', 'label' => 'manager_email', 'value' => nil }],
745
+ 'first_name' => 'first name 1',
746
+ 'last_name' => 'last name 1',
747
+ 'groups' => [],
748
+ 'roles' => []
749
+ }
750
+
751
+ connector.fetch_user_hash('user2@example.com', :identifying_field => 'email').should == {
752
+ 'account_type' => 'member',
753
+ 'contact_info' => {
754
+ 'email' => 'user2@example.com'
755
+ },
756
+ 'custom_fields' => [{ 'id' => 'manager_email', 'label' => 'manager_email', 'value' => nil }],
757
+ 'first_name' => 'first name 2',
758
+ 'last_name' => 'last name 2',
759
+ 'groups' => ['sales_group_id'],
760
+ 'roles' => []
761
+ }
762
+ end
763
+ end
654
764
  end
655
765
 
656
766
  describe "#grab" do
@@ -661,7 +771,7 @@ describe Socialcast::CommandLine::LDAPConnector do
661
771
  "email" => "mail"
662
772
  }
663
773
  end
664
- let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config, ldap) }
774
+ let(:connector) { Socialcast::CommandLine::LDAPConnector.new('connection_1', ldap_config) }
665
775
  let(:entry) do
666
776
  Net::LDAP::Entry.new("cn=sean,dc=example,dc=com").tap do |e|
667
777
  e[:mail] = 'sean@example.com'
@@ -670,12 +780,12 @@ describe Socialcast::CommandLine::LDAPConnector do
670
780
  let(:ldap_instance) { double(Net::LDAP, :encryption => nil, :auth => nil) }
671
781
  context "passed hash for attribute" do
672
782
  it "returns a string that used defined string template" do
673
- connector.grab(entry, { "value" => "123%{mail}", "mail" => "mail" }).should == "123sean@example.com"
783
+ connector.send(:grab, entry, { "value" => "123%{mail}", "mail" => "mail" }).should == "123sean@example.com"
674
784
  end
675
785
  end
676
786
  context "passed string for attribute" do
677
787
  it "returns exact string stored in entry" do
678
- connector.grab(entry, "mail").should == "sean@example.com"
788
+ connector.send(:grab, entry, "mail").should == "sean@example.com"
679
789
  end
680
790
  end
681
791
  context "passed string that can be constantized and the resulting Class responds to run" do
@@ -687,7 +797,7 @@ describe Socialcast::CommandLine::LDAPConnector do
687
797
  end
688
798
  end
689
799
  end
690
- connector.grab(entry, "Socialcast::CommandLine::FakeAttributeMap").should == "sebn@exbmple.com"
800
+ connector.send(:grab, entry, "Socialcast::CommandLine::FakeAttributeMap").should == "sebn@exbmple.com"
691
801
  end
692
802
  end
693
803
  context "passed string that must be classified and the resulting Class responds to run" do
@@ -699,7 +809,7 @@ describe Socialcast::CommandLine::LDAPConnector do
699
809
  end
700
810
  end
701
811
  end
702
- connector.grab(entry, "socialcast/command_line/fake_attribute_map").should == "sebn@exbmple.com"
812
+ connector.send(:grab, entry, "socialcast/command_line/fake_attribute_map").should == "sebn@exbmple.com"
703
813
  end
704
814
  end
705
815
  context "attribute passed has a collision between string and Class" do
@@ -714,7 +824,7 @@ describe Socialcast::CommandLine::LDAPConnector do
714
824
  Object.send(:remove_const, :Mail)
715
825
  end
716
826
  it "returns the result of the Class run method" do
717
- connector.grab(entry, "mail").should == "sebn@exbmple.com"
827
+ connector.send(:grab, entry, "mail").should == "sebn@exbmple.com"
718
828
  end
719
829
  end
720
830
  context "attribute passed constantizes to a module instead of a class" do
@@ -724,7 +834,7 @@ describe Socialcast::CommandLine::LDAPConnector do
724
834
  return "#{entry[:mail].first.gsub(/a/,'b')}"
725
835
  end
726
836
  end
727
- connector.grab(entry, "FakeAttributeMap").should == "sebn@exbmple.com"
837
+ connector.send(:grab, entry, "FakeAttributeMap").should == "sebn@exbmple.com"
728
838
  end
729
839
  end
730
840
  end
@@ -12,7 +12,7 @@ describe Socialcast::CommandLine::ProvisionPhoto do
12
12
 
13
13
  let(:ldap) do
14
14
  ldap_instance = double(Net::LDAP, :auth => nil, :encryption => nil)
15
- ldap_instance.should_receive(:open).and_yield(ldap_instance)
15
+ ldap_instance.should_receive(:open).and_yield
16
16
  Net::LDAP.should_receive(:new).and_return(ldap_instance)
17
17
  ldap_instance
18
18
  end
@@ -143,13 +143,13 @@ describe Socialcast::CommandLine::ProvisionPhoto do
143
143
  stub_const("Socialcast::CommandLine::ProvisionPhoto::MAX_BATCH_SIZE", 2)
144
144
 
145
145
  ldap_instance1 = double(Net::LDAP, :encryption => nil, :auth => nil)
146
- ldap_instance1.should_receive(:open).and_yield(ldap_instance1)
146
+ ldap_instance1.should_receive(:open).and_yield
147
147
  Net::LDAP.should_receive(:new).once.ordered.and_return(ldap_instance1)
148
148
  entry1 = create_entry 'user', :mailCon => 'user@example.com', :photoCon => binary_photo_data
149
149
  ldap_instance1.should_receive(:search).once.with(hash_including(:attributes => ['mailCon', 'photoCon'])).and_yield(entry1)
150
150
 
151
151
  ldap_instance2 = double(Net::LDAP, :encryption => nil, :auth => nil)
152
- ldap_instance2.should_receive(:open).and_yield(ldap_instance2)
152
+ ldap_instance2.should_receive(:open).and_yield
153
153
  Net::LDAP.should_receive(:new).once.ordered.and_return(ldap_instance2)
154
154
  entry2 = create_entry 'user', :mailCon2 => 'user2@example.com', :photoCon2 => binary_photo_data
155
155
  ldap_instance2.should_receive(:search).once.with(hash_including(:attributes => ['mailCon2', 'photoCon2'])).and_yield(entry2)
@@ -19,7 +19,7 @@ describe Socialcast::CommandLine::ProvisionUser do
19
19
 
20
20
  let(:ldap) do
21
21
  ldap_instance = double(Net::LDAP, :auth => nil, :encryption => nil)
22
- ldap_instance.should_receive(:open).and_yield(ldap_instance)
22
+ ldap_instance.should_receive(:open).and_yield
23
23
  Net::LDAP.should_receive(:new).and_return(ldap_instance)
24
24
  ldap_instance
25
25
  end
@@ -117,13 +117,13 @@ describe Socialcast::CommandLine::ProvisionUser do
117
117
  provision_instance = Socialcast::CommandLine::ProvisionUser.new(ldap_multiple_connection_mapping_config, {})
118
118
 
119
119
  ldap_instance1 = double(Net::LDAP, :encryption => nil, :auth => nil)
120
- ldap_instance1.should_receive(:open).and_yield(ldap_instance1)
120
+ ldap_instance1.should_receive(:open).and_yield
121
121
  Net::LDAP.should_receive(:new).once.ordered.and_return(ldap_instance1)
122
122
  entry1 = create_entry 'user', :mailCon => 'user@example.com', :givenName => 'first name', :sn => 'last name'
123
123
  ldap_instance1.should_receive(:search).once.with(hash_including(:attributes => ['mailCon', 'isMemberOf'])).and_yield(entry1)
124
124
 
125
125
  ldap_instance2 = double(Net::LDAP, :encryption => nil, :auth => nil)
126
- ldap_instance2.should_receive(:open).and_yield(ldap_instance2)
126
+ ldap_instance2.should_receive(:open).and_yield
127
127
  Net::LDAP.should_receive(:new).once.ordered.and_return(ldap_instance2)
128
128
  entry2 = create_entry 'user', :mailCon2 => 'user2@example.com', :firstName => 'first name2', :sn => 'last name2'
129
129
  ldap_instance2.should_receive(:search).once.with(hash_including(:attributes => ['mailCon2', 'firstName', 'isMemberOf'])).and_yield(entry2)
@@ -177,7 +177,7 @@ describe Socialcast::CommandLine::ProvisionUser do
177
177
  provision_instance = Socialcast::CommandLine::ProvisionUser.new(ldap_with_manager_attribute_config, {})
178
178
 
179
179
  ldap_instance = double(Net::LDAP, :encryption => nil, :auth => nil)
180
- ldap_instance.should_receive(:open).and_yield(ldap_instance)
180
+ ldap_instance.should_receive(:open).and_yield
181
181
  Net::LDAP.should_receive(:new).once.and_return(ldap_instance)
182
182
 
183
183
  user_entry = create_entry 'user', :mail => 'user@example.com', :ldap_manager => 'cn=theboss,dc=example,dc=com'
@@ -375,13 +375,13 @@ describe Socialcast::CommandLine::ProvisionUser do
375
375
  provision_instance = Socialcast::CommandLine::ProvisionUser.new(ldap_multiple_connection_permission_mapping_config, {})
376
376
 
377
377
  ldap_instance1 = double(Net::LDAP, :encryption => nil, :auth => nil)
378
- ldap_instance1.should_receive(:open).and_yield(ldap_instance1)
378
+ ldap_instance1.should_receive(:open).and_yield
379
379
  Net::LDAP.should_receive(:new).once.ordered.and_return(ldap_instance1)
380
380
  entry1 = create_entry 'user', :mail => 'user@example.com', :givenName => 'first name', :sn => 'last name', :memberOf => ["cn=External,dc=example,dc=com", "cn=SbiAdmins,dc=example,dc=com", "cn=TownHallAdmins,dc=example,dc=com"]
381
381
  ldap_instance1.should_receive(:search).once.with(hash_including(:attributes => ['givenName', 'sn', 'mail', 'memberOf'])).and_yield(entry1)
382
382
 
383
383
  ldap_instance2 = double(Net::LDAP, :encryption => nil, :auth => nil)
384
- ldap_instance2.should_receive(:open).and_yield(ldap_instance2)
384
+ ldap_instance2.should_receive(:open).and_yield
385
385
  Net::LDAP.should_receive(:new).once.ordered.and_return(ldap_instance2)
386
386
  entry2 = create_entry 'user', :mail => 'user@example.com', :givenName => 'first name', :sn => 'last name', :member => ["cn=Contractors,dc=example,dc=com", "cn=SbiAdmins,dc=example,dc=com", "cn=TownHallAdmins,dc=example,dc=com"]
387
387
  ldap_instance2.should_receive(:search).once.with(hash_including(:attributes => ['givenName', 'sn', 'mail', 'member'])).and_yield(entry2)
@@ -411,7 +411,7 @@ describe Socialcast::CommandLine::ProvisionUser do
411
411
  root_entry = create_entry('domain', :namingcontexts => ['dc=foo,dc=com', 'dc=bar,dc=com'])
412
412
  ldap_instance = double(Net::LDAP, :encryption => nil, :auth => nil)
413
413
  ldap_instance.should_receive(:search_root_dse).once.and_return(root_entry)
414
- ldap_instance.should_receive(:open).and_yield(ldap_instance)
414
+ ldap_instance.should_receive(:open).and_yield
415
415
  Net::LDAP.should_receive(:new).once.and_return(ldap_instance)
416
416
 
417
417
  user_entry = create_entry 'user', :mail => 'user@example.com', :givenName => 'first name', :sn => 'last name'
@@ -474,14 +474,14 @@ describe Socialcast::CommandLine::ProvisionUser do
474
474
  let(:entry) { create_entry 'user', :mailCon2 => 'user@example.com', :firstName => 'first name' }
475
475
  before do
476
476
  ldap_instance1 = double(Net::LDAP, :auth => nil)
477
- ldap_instance1.should_receive(:open).and_yield(ldap_instance1)
477
+ ldap_instance1.should_receive(:open).and_yield
478
478
  Net::LDAP.should_receive(:new).once.ordered.and_return(ldap_instance1)
479
479
  filter1 = Net::LDAP::Filter.construct('(&(mail=*)(mailCon=user@example.com))')
480
480
  ldap_instance1.should_receive(:search).once.ordered
481
481
  .with(hash_including(:attributes => ['mailCon', 'isMemberOf'], :filter => filter1))
482
482
 
483
483
  ldap_instance2 = double(Net::LDAP, :auth => nil)
484
- ldap_instance2.should_receive(:open).and_yield(ldap_instance2)
484
+ ldap_instance2.should_receive(:open).and_yield
485
485
  Net::LDAP.should_receive(:new).once.ordered.and_return(ldap_instance2)
486
486
  filter2 = Net::LDAP::Filter.construct('(&(mail=*)(mailCon2=user@example.com))')
487
487
  ldap_instance2.should_receive(:search).once.ordered
@@ -505,14 +505,14 @@ describe Socialcast::CommandLine::ProvisionUser do
505
505
  let(:provision_instance) { Socialcast::CommandLine::ProvisionUser.new(ldap_multiple_connection_mapping_config, {}) }
506
506
  before do
507
507
  ldap_instance1 = double(Net::LDAP, :auth => nil)
508
- ldap_instance1.should_receive(:open).and_yield(ldap_instance1)
508
+ ldap_instance1.should_receive(:open).and_yield
509
509
  Net::LDAP.should_receive(:new).once.ordered.and_return(ldap_instance1)
510
510
  filter1 = Net::LDAP::Filter.construct('(&(mail=*)(mailCon=user@example.com))')
511
511
  ldap_instance1.should_receive(:search)
512
512
  .with(hash_including(:attributes => ['mailCon', 'isMemberOf'], :filter => filter1))
513
513
 
514
514
  ldap_instance2 = double(Net::LDAP, :auth => nil)
515
- ldap_instance2.should_receive(:open).and_yield(ldap_instance2)
515
+ ldap_instance2.should_receive(:open).and_yield
516
516
  Net::LDAP.should_receive(:new).once.ordered.and_return(ldap_instance2)
517
517
  filter2 = Net::LDAP::Filter.construct('(&(mail=*)(mailCon2=user@example.com))')
518
518
  ldap_instance2.should_receive(:search).once.ordered
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: socialcast
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.11
4
+ version: 1.3.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Sonnek
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-06-11 00:00:00.000000000 Z
13
+ date: 2014-06-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rest-client