socialcast 1.3.11 → 1.3.12

Sign up to get free protection for your applications and to get access to all the features.
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