ansible/roles/ldap_gravatar/files/gravatar-update.py

72 lines
2 KiB
Python
Executable file

#!/usr/bin/python3
import urllib
import syslog
import hashlib
import ldap3
import requests
def ldap_connect():
server = ldap3.Server("ldapi:///var/run/ldapi")
conn = ldap3.Connection(
server,
authentication=ldap3.SASL,
sasl_mechanism=ldap3.EXTERNAL,
sasl_credentials="",
client_strategy=ldap3.SYNC,
)
conn.bind()
conn.search(
search_base="",
search_filter="(objectClass=*)",
search_scope=ldap3.BASE,
attributes=["namingContexts"],
)
basedn = conn.response[0]["attributes"]["namingContexts"][0]
return (conn, basedn)
def get_users(conn, basedn):
conn.search(
search_base=basedn,
search_filter="(&(mail=*)(objectClass=inetOrgPerson))",
attributes=["mail", "jpegPhoto"],
)
for result in conn.response:
yield (result["dn"], result["attributes"])
def get_avatar(emails):
for email in emails:
mailhash = hashlib.md5(email.encode("utf-8").lower()).hexdigest()
url = f"https://gravatar.com/avatar/{mailhash}.jpg?d=404&size=80"
req = requests.get(url)
if req.status_code == 200:
return req.content
elif req.status_code == 404:
continue
raise ValueError(f"Invalid response from gravatar {req.status_code}")
return None
def update_avatar(conn, dn, image):
if image is None:
syslog.syslog(syslog.LOG_INFO, f"Removing jpegPhoto from user '{dn}'")
data = (ldap3.MODIFY_REPLACE, [])
else:
syslog.syslog(syslog.LOG_INFO, f"Updating jpegPhoto for user '{dn}'")
data = (ldap3.MODIFY_REPLACE, [image])
conn.modify(dn, {"jpegPhoto": [data]})
if __name__ == "__main__":
syslog.openlog()
(conn, basedn) = ldap_connect()
for (dn, user) in get_users(conn, basedn):
image = get_avatar(user["mail"])
if len(user["jpegPhoto"]) == 1 and user["jpegPhoto"][0] == image:
continue
update_avatar(conn, dn, image)
syslog.closelog()