ldap_disambiguate 0.0.1 → 0.0.2

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: 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