From 015de5a8dfe2b88c2d8e64d42ee5d7b7c975284a Mon Sep 17 00:00:00 2001 From: Timo Makinen Date: Tue, 16 Mar 2021 19:18:55 +0000 Subject: [PATCH] ldap_gravatar: Initial version of role --- roles/ldap_gravatar/files/gravatar-update.py | 72 ++++++++++++++++++++ roles/ldap_gravatar/tasks/main.yml | 25 +++++++ 2 files changed, 97 insertions(+) create mode 100755 roles/ldap_gravatar/files/gravatar-update.py create mode 100644 roles/ldap_gravatar/tasks/main.yml diff --git a/roles/ldap_gravatar/files/gravatar-update.py b/roles/ldap_gravatar/files/gravatar-update.py new file mode 100755 index 0000000..62706af --- /dev/null +++ b/roles/ldap_gravatar/files/gravatar-update.py @@ -0,0 +1,72 @@ +#!/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() diff --git a/roles/ldap_gravatar/tasks/main.yml b/roles/ldap_gravatar/tasks/main.yml new file mode 100644 index 0000000..fe04f79 --- /dev/null +++ b/roles/ldap_gravatar/tasks/main.yml @@ -0,0 +1,25 @@ +--- + +- name: install dependencies + package: + name: "{{ item }}" + state: installed + with_items: + - python3-ldap3 + - python3-requests + +- name: install script + copy: + src: gravatar-update.py + dest: /usr/local/sbin/gravatar-update + mode: 755 + owner: root + group: "{{ ansible_wheel }}" + +- name: install cron job + cron: + name: gravatar-update + hour: "05" + minute: "10" + job: /usr/local/sbin/gravatar-update +