summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKelley Spoon <kelley.spoon@linaro.org>2019-01-08 08:50:04 -0600
committerKelley Spoon <kelley.spoon@linaro.org>2019-01-09 11:14:49 -0600
commit97a9caf19097ef2f770a7024051dc22670640735 (patch)
treebf1669f0b632a4016056765af8f18c82b70b2df1
parentab13703912aa4ed6254b23fb16cb585f1a1385eb (diff)
downloadpatchwork-tools-97a9caf19097ef2f770a7024051dc22670640735.tar.gz
alt_email.py: Add in script to generate GL identities list
This script sifts through the patchworks database and tries to create grimoirelabs identies file that is capable of detecting users with multiple email addresses and accounts and also associate user accounts with their member companies. Change-Id: I649f686ee48ff3951c116977127d6001c25f57d7
-rwxr-xr-xalt_email.py150
1 files changed, 150 insertions, 0 deletions
diff --git a/alt_email.py b/alt_email.py
new file mode 100755
index 0000000..523bfe5
--- /dev/null
+++ b/alt_email.py
@@ -0,0 +1,150 @@
+#!/usr/bin/python
+""" A script to export an identities.yaml file from Patchworks that
+ attempts to cross-reference with user information from LDAP.
+
+ This script shold be run with the following exports:
+ export PYTHONPATH=$PYTHONPATH:../project:/srv/linaro-git-tools
+ export DJANGO_SETTINGS_MODULE=local_settings
+"""
+
+import sys
+import os
+from datetime import datetime
+from jinja2 import Template
+import linaro_ldap
+from patchwork.models import User
+from patchwork.models import Person
+import django
+
+django.setup()
+
+# hack to make python 2.7 use unicode by default
+# since some of our usernames have non-ascii chars
+reload(sys)
+sys.setdefaultencoding('utf8')
+
+OUTFILE = "/tmp/patchworks-identities.yaml"
+
+if os.path.isfile(OUTFILE):
+ os.unlink(OUTFILE)
+
+MEMBER_DOMAINS_TABLE = {}
+
+
+class NoLdapUserException(Exception):
+ pass
+
+
+def build_member_table():
+ """ Builds a lookup table using email domains as the key to match
+ email addresses with member organizations. """
+ member_ous = linaro_ldap.do_complex_query(
+ search_filter='(organizationalStatus=*)',
+ attrlist=['*'])
+
+ for mou in member_ous:
+ member_name = mou[1]["description"][0]
+ if "mail" in mou[1]:
+ for domain in mou[1]["mail"]:
+ MEMBER_DOMAINS_TABLE[domain] = member_name
+
+
+def get_name(target_email, target_attr='displayName'):
+ """ Attempts to get the user's real name from LDAP based on email address.
+ Raises an NoLdapUserException if the user is not found, otherwise
+ returns the "target_attr" setting from LDAP (defaults to
+ "displayName")."""
+ result = linaro_ldap.do_query(
+ search_attr='mail',
+ search_pat=target_email,
+ attrlist=[target_attr])
+ if result and target_attr in result[0][1]:
+ return result[0][1][target_attr][0]
+
+ raise NoLdapUserException(
+ "no user found in LDAP for %s" % target_email)
+
+
+def get_org(target_emails):
+ """ Attempts to determine the organization a user belongs to based
+ on their email addresses. Look first for a linaro.org address,
+ then searches through member domains. If nothing is found,
+ returns 'Unknown' as default. """
+ # if they have a l.o address, claim them
+ for x in target_emails:
+ if x.endswith('@linaro.org'):
+ return 'Linaro'
+
+ # if still here, see if we can match a domain to a member
+ for x in target_emails:
+ domain = x.split('@')[-1]
+ if domain in MEMBER_DOMAINS_TABLE:
+ return MEMBER_DOMAINS_TABLE[domain]
+
+ return 'Unknown'
+
+
+TMPL = Template(u'''\
+- profile:
+ name: {{ username }}
+ enrollments:
+ - organization: {{ org }}
+{%- if end_date %}
+ end_date: {{ end_date }}
+{%- endif -%}
+ email:
+{%- for email in emails %}
+ - {{ email }}
+{%- endfor %}
+
+''')
+
+
+def write_entry(uid, target_emails, target_org, target_end_date=None):
+ """ Write a profile entry for the specified user to output """
+ try:
+
+ entry_template = TMPL.render(
+ username=uid,
+ org=target_org,
+ end_date=target_end_date,
+ emails=target_emails
+ )
+ with open(OUTFILE, 'a') as outfile:
+ outfile.write(entry_template)
+ except TypeError:
+ pass
+
+
+build_member_table()
+
+for user in User.objects.filter(is_active=True):
+ persons = Person.objects.filter(user=user)
+ # concat all emails from Person objs, but skip '(address hidden)'
+ emails = [x.email for x in persons if '@' in x.email]
+
+ # some cases we have a linaro Person linked to non-Linaro User..
+ # make sure their email is included before we start looking
+ # for organization membership
+ if '@' in user.username and user.username not in emails:
+ emails.append(user.username)
+
+ # don't bother if user just has an account but no email addresses
+ if not emails:
+ continue
+
+ org = get_org(emails)
+
+ end_date = None
+
+ if org == 'Linaro':
+ linaro_email = [x for x in emails if x.endswith('@linaro.org')].pop()
+ try:
+ name = get_name(linaro_email, "displayName")
+ except NoLdapUserException:
+ name = user.username
+ end_date = str(datetime.now())
+ else:
+ name = user.username
+
+ write_entry(name, emails, org, end_date)