ldap_disambiguate 0.0.1 → 0.0.2

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: 76ca8867744e6cb0102707bf64529554acdccd14
4
- data.tar.gz: 3a7fc8ab6ca648fd67d0113ca541968123d37f37
3
+ metadata.gz: 3e7e4f4bcbf3f618e74f3cfb914cb11ccf49cad2
4
+ data.tar.gz: c6c4ac00bfab448d2685ccdced45e98da58ba1f2
5
5
  SHA512:
6
- metadata.gz: b25d698df46f01b22f019cbfa79f337729e4be4f655862d6261623df0a58aaafd5fc2e13de26ab0d2345a943ca5e2a1bb76eaec044b4aeac7dc0fb101a45aa3e
7
- data.tar.gz: ded15695850d2820b7cb4c98662fc8f6a58efb93b7478647b20e966437a7830d8144c4bf10f086254f9091e00a6637cb1dd26aa46e50514b44d3d8fb6373d5f3
6
+ metadata.gz: f9067937965edf6fbd2e7f225c333ea9adc35a2d0bde3c4009c0501c28440366a2826c0c61156565726b70165fe2b91343d149dd30a6e0ab10086f4e2557668d
7
+ data.tar.gz: de9965cae77d76570b13a6d3c4f7b6819c101710c34724179787bd388361d75617086eca5496ae212ae9bb393ce9bef25918a46cf9093f3e40fe13b45c3309d7
@@ -41,17 +41,17 @@ Style/SingleLineBlockParams:
41
41
  Style/SignalException:
42
42
  Enabled: false
43
43
 
44
- RSpec/ExampleWording:
45
- CustomTransform:
46
- be: is
47
- have: has
48
- not: does not
49
- NOT: does NOT
50
- IgnoredWords:
51
- - only
52
-
53
- RSpec/FilePath:
54
- Enabled: false
55
-
56
- RSpec/InstanceVariable:
57
- Enabled: false
44
+ #RSpec/ExampleWording:
45
+ # CustomTransform:
46
+ # be: is
47
+ # have: has
48
+ # not: does not
49
+ # NOT: does NOT
50
+ # IgnoredWords:
51
+ # - only
52
+ #
53
+ #RSpec/FilePath:
54
+ # Enabled: false
55
+ #
56
+ #RSpec/InstanceVariable:
57
+ # Enabled: false
data/Gemfile CHANGED
@@ -6,4 +6,3 @@ gemspec
6
6
 
7
7
  gem 'byebug'
8
8
  gem 'rubocop', require: false
9
- gem 'rubocop-rspec', require: false
data/Rakefile CHANGED
@@ -18,7 +18,6 @@ RSpec::Core::RakeTask.new(:spec)
18
18
 
19
19
  desc "Run style checker"
20
20
  RuboCop::RakeTask.new(:rubocop) do |task|
21
- task.requires << 'rubocop-rspec'
22
21
  task.fail_on_error = true
23
22
  end
24
23
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
  s.add_dependency 'hydra-ldap'
25
25
  s.add_dependency 'net-ldap', '0.13.0'
26
26
  s.add_dependency 'namae', '0.9.3'
27
+ s.add_dependency 'mail', '~> 2.6'
27
28
 
28
29
  s.add_development_dependency 'bundler', '~> 1.11'
29
30
  s.add_development_dependency 'rake', '~> 10.0'
@@ -4,6 +4,7 @@ require 'net-ldap'
4
4
  require 'hydra-ldap'
5
5
  require 'namae'
6
6
  require 'logger'
7
+ require 'mail'
7
8
 
8
9
  def logger
9
10
  Logger.new(STDOUT)
@@ -19,4 +20,5 @@ module LdapDisambiguate
19
20
  autoload :Name, 'ldap_disambiguate/name'
20
21
  autoload :Email, 'ldap_disambiguate/email'
21
22
  autoload :LdapUser, 'ldap_disambiguate/ldap_user'
23
+ autoload :MultipleUserError, 'ldap_disambiguate/multiple_user_error'
22
24
  end
@@ -7,24 +7,8 @@ module LdapDisambiguate
7
7
  private
8
8
 
9
9
  def ldap_attributes_for_id(id)
10
- attrs = LdapUser.directory_attributes(id, ldap_attrs)
11
- return nil if attrs.count < 1
12
- [results_hash(attrs.first)]
13
- end
14
-
15
- def results_hash(opts)
16
- {
17
- id: fetch(opts, :uid).first,
18
- given_name: fetch(opts, :givenname).first,
19
- surname: fetch(opts, :sn).first,
20
- email: fetch(opts, :mail).first,
21
- affiliation: fetch(opts, :eduPersonPrimaryAffiliation, []),
22
- displayname: fetch(opts, :displayname).first
23
- }
24
- end
25
-
26
- def fetch(opts, key, default = [''])
27
- opts[key].blank? ? default : opts[key]
10
+ users = LdapUser.directory_attributes(id, ldap_attrs)
11
+ users.count < 1 ? nil : users
28
12
  end
29
13
 
30
14
  def ldap_attrs
@@ -16,12 +16,17 @@ module LdapDisambiguate
16
16
  parts = email_list.split(' ')
17
17
  emails = parts.reject { |part| !part.include?('@') }
18
18
  results = []
19
- Array(emails).each do |email|
20
- id = email.split('@')[0]
21
- results << (ldap_attributes_for_id(id) || [results_hash(mail: [email])]).first
19
+ Array(emails).each do |email_str|
20
+ email = Mail::Address.new(email_str)
21
+ results << (ldap_attributes_for_id(email.local) || ldap_attributes_for_email(email.address) || [LdapUser.results_hash(mail: [email.address])]).first
22
22
  end
23
23
  results
24
24
  end
25
+
26
+ def ldap_attributes_for_email(email)
27
+ users = LdapUser.query_ldap_by_mail(email, ldap_attrs)
28
+ users.count < 1 ? nil : users
29
+ end
25
30
  end
26
31
  end
27
32
  end
@@ -6,16 +6,14 @@ module LdapDisambiguate
6
6
  class << self
7
7
  def directory_attributes(login, attrs = [])
8
8
  filter = Net::LDAP::Filter.eq('uid', login)
9
- get_ldap_response(:get_user, filter, attrs)
9
+ result = get_ldap_response(filter, attrs)
10
+ format_users(result, attrs)
10
11
  end
11
12
 
12
- def query_ldap_by_name_or_id(id_or_name_part)
13
- filter = Net::LDAP::Filter.construct("(& (| (uid=#{id_or_name_part}* ) (givenname=#{id_or_name_part}*) (sn=#{id_or_name_part}*)) #{person_filter})")
14
- users = get_ldap_response(:get_user, filter, %w(uid displayname))
15
-
16
- # handle the issue that searching with a few letters returns more than 1000 items wich causes an error in the system
17
- users = get_user_by_partial_id(id_or_name_part) if size_limit_exceeded?
18
- users.map { |u| { id: u[:uid].first, text: "#{u[:displayname].first} (#{u[:uid].first})" } }
13
+ def query_ldap_by_mail(email, attrs = [])
14
+ filter = Net::LDAP::Filter.construct("(& (| (psmailid=#{email} ) (mail=#{email}) (psmailbox=#{email}) (edupersonprincipalname=#{email})) #{person_filter})")
15
+ users = get_users(filter, attrs)
16
+ format_users(users, attrs)
19
17
  end
20
18
 
21
19
  def query_ldap_by_name(given_name, surname, attrs = [])
@@ -32,33 +30,51 @@ module LdapDisambiguate
32
30
 
33
31
  def get_users(name_filter, attrs = [])
34
32
  attrs = (attrs + default_attributes).uniq
35
- person_filter = '(| (eduPersonPrimaryAffiliation=STUDENT) (eduPersonPrimaryAffiliation=FACULTY) (eduPersonPrimaryAffiliation=STAFF) (eduPersonPrimaryAffiliation=EMPLOYEE) (eduPersonPrimaryAffiliation=RETIREE) (eduPersonPrimaryAffiliation=EMERITUS) (eduPersonPrimaryAffiliation=MEMBER)))'
36
33
  filter = Net::LDAP::Filter.construct("(& (& #{name_filter}) #{person_filter})")
37
- get_ldap_response(:get_user, filter, attrs)
34
+ get_ldap_response(filter, attrs)
35
+ end
36
+
37
+ def results_hash(opts)
38
+ {
39
+ id: fetch(opts, :uid).first,
40
+ given_name: fetch(opts, :givenname).first,
41
+ surname: fetch(opts, :sn).first,
42
+ email: fetch(opts, :mail).first,
43
+ affiliation: fetch(opts, :eduPersonPrimaryAffiliation, []),
44
+ displayname: fetch(opts, :displayname).first
45
+ }
38
46
  end
39
47
 
40
48
  private
41
49
 
50
+ def fetch(opts, key, default = [''])
51
+ opts[key].blank? ? default : opts[key]
52
+ end
53
+
42
54
  def format_users(users, attrs)
43
55
  user_attrs = attrs - default_attributes
44
56
  users.map { |u| format_user(u, user_attrs) }
45
57
  end
46
58
 
47
59
  def format_user(user, extra_attrs)
48
- hash = { id: user[:uid].first, given_name: user[:givenname].first, surname: user[:sn].first, email: user[:mail].first, affiliation: user[:eduPersonPrimaryAffiliation] }
60
+ hash = results_hash(user)
49
61
  extra_attrs.each { |attr| hash[attr] = user[attr].first }
50
62
  hash
51
63
  end
52
64
 
53
- def get_user_by_partial_id(_id)
54
- filter = Net::LDAP::Filter.construct("(& (uid=#{id_or_name_part}* ) #{person_filter})")
55
- get_ldap_response(:get_user, filter, %w(uid displayname))
65
+ def get_user_by_partial_id(id)
66
+ filter = Net::LDAP::Filter.construct("(& (uid=#{id}* ) #{person_filter})")
67
+ get_ldap_response(filter, %w(uid displayname))
56
68
  end
57
69
 
58
- def get_ldap_response(_method, filter, attributes)
70
+ def get_ldap_response(filter, attributes)
71
+ return cache[filter.to_s] if cache.key?(filter.to_s)
59
72
  tries.times.each do
60
73
  result = Hydra::LDAP.get_user(filter, attributes)
61
- return result unless unwilling?
74
+ unless unwilling?
75
+ cache[filter.to_s] = result
76
+ return result
77
+ end
62
78
  sleep(sleep_time)
63
79
  end
64
80
  nil
@@ -82,7 +98,7 @@ module LdapDisambiguate
82
98
  end
83
99
 
84
100
  def person_filter
85
- '(| (eduPersonPrimaryAffiliation=STUDENT) (eduPersonPrimaryAffiliation=FACULTY) (eduPersonPrimaryAffiliation=STAFF) (eduPersonPrimaryAffiliation=EMPLOYEE))))'
101
+ '(| (eduPersonPrimaryAffiliation=STUDENT) (eduPersonPrimaryAffiliation=FACULTY) (eduPersonPrimaryAffiliation=STAFF) (eduPersonPrimaryAffiliation=EMPLOYEE) (eduPersonPrimaryAffiliation=RETIREE) (eduPersonPrimaryAffiliation=EMERITUS) (eduPersonPrimaryAffiliation=MEMBER)))'
86
102
  end
87
103
 
88
104
  def name_filters(first_name, middle_name, surname)
@@ -95,7 +111,11 @@ module LdapDisambiguate
95
111
  end
96
112
 
97
113
  def default_attributes
98
- [:uid, :givenname, :sn, :mail, :eduPersonPrimaryAffiliation]
114
+ [:uid, :givenname, :sn, :mail, :eduPersonPrimaryAffiliation, :displayname]
115
+ end
116
+
117
+ def cache
118
+ @cache ||= {}
99
119
  end
100
120
  end
101
121
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+ module LdapDisambiguate
3
+ # This error is thrown if we get more than one user back from ldap for an input
4
+ #
5
+ class MultipleUserError < RuntimeError
6
+ end
7
+ end
@@ -17,15 +17,21 @@ module LdapDisambiguate
17
17
  def text_only_names(multi_name)
18
18
  results = []
19
19
  multi_name.split(/and|;/).each do |n|
20
- n.gsub!(/\([^)]*\)/, '')
21
- n.strip!
22
- query_result = email_for_name(n)
23
- query_result ||= title_after_name(n) # try again without the titles
24
- results << query_result unless query_result.blank?
20
+ result = text_only_name(n)
21
+ results << result unless result.blank?
25
22
  end
26
23
  results
27
24
  end
28
25
 
26
+ def text_only_name(name)
27
+ name = clean_name(name)
28
+ query_result = email_for_name(name)
29
+ query_result ||= title_after_name(name) # try again without the titles
30
+ return query_result
31
+ rescue MultipleUserError
32
+ return nil
33
+ end
34
+
29
35
  # titles after the name that namae had trouble parsing
30
36
  def title_after_name(text_name)
31
37
  result = nil
@@ -54,19 +60,14 @@ module LdapDisambiguate
54
60
  result = try_name(parsed.given, parsed.family)
55
61
  result ||= title_before_name(parsed)
56
62
  result ||= two_words_in_last_name(text_name)
57
-
58
- logger.error("got zero for #{text_name}") if result.nil?
59
63
  result
60
64
  end
61
65
 
62
66
  def try_name(given, family)
63
67
  return nil if family.blank?
64
68
  possible_users = LdapUser.query_ldap_by_name(given, family, ldap_attrs)
65
- return nil if possible_users.count == 0
66
- if possible_users.count > 1
67
- logger.error("Returning #{possible_users.first} but got more than name for given name #{given} and family name #{name}")
68
- return nil
69
- end
69
+ return nil if possible_users.blank? || possible_users.count == 0
70
+ raise(MultipleUserError, "too name results for #{given} #{family}") if possible_users.count > 1
70
71
  possible_users.first
71
72
  end
72
73
 
@@ -90,12 +91,16 @@ module LdapDisambiguate
90
91
 
91
92
  def two_words_in_last_name(text_name)
92
93
  result = nil
93
- if text_name.count(' ') > 2
94
+ if text_name.strip.count(' ') > 2
94
95
  parts = name_parts(text_name, 2)
95
96
  result = try_name(parts[:given], parts[:family])
96
97
  end
97
98
  result
98
99
  end
100
+
101
+ def clean_name(name)
102
+ name.gsub(/\([^)]*\)/, '').strip
103
+ end
99
104
  end
100
105
  end
101
106
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module LdapDisambiguate
3
- VERSION = '0.0.1'.freeze
3
+ VERSION = '0.0.2'.freeze
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ldap_disambiguate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carolyn Cole
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.9.3
55
+ - !ruby/object:Gem::Dependency
56
+ name: mail
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.6'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.6'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: bundler
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -129,6 +143,7 @@ files:
129
143
  - lib/ldap_disambiguate/base.rb
130
144
  - lib/ldap_disambiguate/email.rb
131
145
  - lib/ldap_disambiguate/ldap_user.rb
146
+ - lib/ldap_disambiguate/multiple_user_error.rb
132
147
  - lib/ldap_disambiguate/name.rb
133
148
  - lib/ldap_disambiguate/version.rb
134
149
  homepage: https://github.com/psu-stewardship/ldap_disambiguate