2020-04-21 00:28:12 +00:00
|
|
|
import os
|
|
|
|
|
2020-04-20 19:16:33 +00:00
|
|
|
from crc import app
|
2020-04-21 00:28:12 +00:00
|
|
|
from ldap3 import Connection, Server, MOCK_SYNC
|
2020-04-20 20:02:13 +00:00
|
|
|
|
|
|
|
from crc.api.common import ApiError
|
2020-04-20 19:16:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
class LdapUserInfo(object):
|
|
|
|
|
|
|
|
def __init__(self, entry):
|
2020-04-20 20:02:13 +00:00
|
|
|
self.display_name = entry.displayName.value
|
2020-04-20 19:16:33 +00:00
|
|
|
self.given_name = ", ".join(entry.givenName)
|
2020-04-20 20:02:13 +00:00
|
|
|
self.email = entry.mail.value
|
2020-05-19 20:11:43 +00:00
|
|
|
self.telephone_number = ", ".join(entry.telephoneNumber)
|
2020-04-20 19:16:33 +00:00
|
|
|
self.title = ", ".join(entry.title)
|
|
|
|
self.department = ", ".join(entry.uvaDisplayDepartment)
|
|
|
|
self.affiliation = ", ".join(entry.uvaPersonIAMAffiliation)
|
|
|
|
self.sponsor_type = ", ".join(entry.uvaPersonSponsoredType)
|
2020-05-19 20:11:43 +00:00
|
|
|
self.uid = entry.uid.value
|
2020-04-20 20:02:13 +00:00
|
|
|
|
|
|
|
|
2020-04-20 19:16:33 +00:00
|
|
|
class LdapService(object):
|
|
|
|
search_base = "ou=People,o=University of Virginia,c=US"
|
2020-05-19 20:11:43 +00:00
|
|
|
attributes = ['uid', 'cn', 'displayName', 'givenName', 'mail', 'objectClass', 'UvaDisplayDepartment',
|
2020-04-20 19:16:33 +00:00
|
|
|
'telephoneNumber', 'title', 'uvaPersonIAMAffiliation', 'uvaPersonSponsoredType']
|
2020-05-19 20:11:43 +00:00
|
|
|
uid_search_string = "(&(objectclass=person)(uid=%s))"
|
2020-04-20 19:16:33 +00:00
|
|
|
|
2020-04-21 00:28:12 +00:00
|
|
|
def __init__(self):
|
|
|
|
if app.config['TESTING']:
|
|
|
|
server = Server('my_fake_server')
|
|
|
|
self.conn = Connection(server, client_strategy=MOCK_SYNC)
|
|
|
|
file_path = os.path.abspath(os.path.join(app.root_path, '..', 'tests', 'data', 'ldap_response.json'))
|
|
|
|
self.conn.strategy.entries_from_json(file_path)
|
|
|
|
self.conn.bind()
|
|
|
|
else:
|
2020-04-20 20:02:13 +00:00
|
|
|
server = Server(app.config['LDAP_URL'], connect_timeout=app.config['LDAP_TIMEOUT_SEC'])
|
|
|
|
self.conn = Connection(server,
|
|
|
|
auto_bind=True,
|
|
|
|
receive_timeout=app.config['LDAP_TIMEOUT_SEC'],
|
|
|
|
)
|
2020-04-20 19:16:33 +00:00
|
|
|
|
|
|
|
def __del__(self):
|
2020-04-20 20:02:13 +00:00
|
|
|
if self.conn:
|
|
|
|
self.conn.unbind()
|
2020-04-20 19:16:33 +00:00
|
|
|
|
|
|
|
def user_info(self, uva_uid):
|
2020-05-19 20:11:43 +00:00
|
|
|
search_string = LdapService.uid_search_string % uva_uid
|
2020-04-20 19:16:33 +00:00
|
|
|
self.conn.search(LdapService.search_base, search_string, attributes=LdapService.attributes)
|
2020-04-20 20:02:13 +00:00
|
|
|
if len(self.conn.entries) < 1:
|
|
|
|
raise ApiError("missing_ldap_record", "Unable to locate a user with id %s in LDAP" % uva_uid)
|
2020-04-20 19:16:33 +00:00
|
|
|
entry = self.conn.entries[0]
|
|
|
|
return(LdapUserInfo(entry))
|
2020-05-19 20:11:43 +00:00
|
|
|
|
|
|
|
def search_users(self, query, limit):
|
|
|
|
search_string = LdapService.uid_search_string % query
|
|
|
|
self.conn.search(LdapService.search_base, search_string, attributes=LdapService.attributes)
|
|
|
|
|
|
|
|
# Entries are returned as a generator, accessing entries
|
|
|
|
# can make subsequent calls to the ldap service, so limit
|
|
|
|
# those here.
|
|
|
|
count = 0
|
|
|
|
results = []
|
|
|
|
for entry in self.conn.entries:
|
|
|
|
if count > limit:
|
|
|
|
break
|
|
|
|
results.append(LdapUserInfo(entry))
|
|
|
|
count += 1
|
|
|
|
return results
|