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 +4 -4
- data/.rubocop.yml +14 -14
- data/Gemfile +0 -1
- data/Rakefile +0 -1
- data/VERSION +1 -1
- data/ldap_disambiguate.gemspec +1 -0
- data/lib/ldap_disambiguate.rb +2 -0
- data/lib/ldap_disambiguate/base.rb +2 -18
- data/lib/ldap_disambiguate/email.rb +8 -3
- data/lib/ldap_disambiguate/ldap_user.rb +38 -18
- data/lib/ldap_disambiguate/multiple_user_error.rb +7 -0
- data/lib/ldap_disambiguate/name.rb +18 -13
- data/lib/ldap_disambiguate/version.rb +1 -1
- metadata +16 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e7e4f4bcbf3f618e74f3cfb914cb11ccf49cad2
|
4
|
+
data.tar.gz: c6c4ac00bfab448d2685ccdced45e98da58ba1f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9067937965edf6fbd2e7f225c333ea9adc35a2d0bde3c4009c0501c28440366a2826c0c61156565726b70165fe2b91343d149dd30a6e0ab10086f4e2557668d
|
7
|
+
data.tar.gz: de9965cae77d76570b13a6d3c4f7b6819c101710c34724179787bd388361d75617086eca5496ae212ae9bb393ce9bef25918a46cf9093f3e40fe13b45c3309d7
|
data/.rubocop.yml
CHANGED
@@ -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
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/ldap_disambiguate.gemspec
CHANGED
@@ -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'
|
data/lib/ldap_disambiguate.rb
CHANGED
@@ -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
|
-
|
11
|
-
|
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 |
|
20
|
-
|
21
|
-
results << (ldap_attributes_for_id(
|
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(
|
9
|
+
result = get_ldap_response(filter, attrs)
|
10
|
+
format_users(result, attrs)
|
10
11
|
end
|
11
12
|
|
12
|
-
def
|
13
|
-
filter = Net::LDAP::Filter.construct("(& (| (
|
14
|
-
users =
|
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(
|
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 =
|
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(
|
54
|
-
filter = Net::LDAP::Filter.construct("(& (uid=#{
|
55
|
-
get_ldap_response(
|
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(
|
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
|
-
|
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
|
@@ -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
|
21
|
-
|
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
|
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.
|
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
|