~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/services/utils.py

  • Committer: Launchpad Patch Queue Manager
  • Date: 2011-07-05 14:31:38 UTC
  • mfrom: (13316.10.21 bug-740208-obfuscate-ws)
  • Revision ID: launchpad@pqm.canonical.com-20110705143138-yd0hdrvbeslquzfm
[r=deryck][bug=740208] obfuscated email addresses for anonymous
 webservice requests

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
    'file_exists',
19
19
    'iter_list_chunks',
20
20
    'iter_split',
 
21
    'obfuscate_email',
 
22
    're_email_address',
21
23
    'run_capturing_output',
22
24
    'synchronize',
23
25
    'text_delta',
29
31
from datetime import datetime
30
32
from itertools import tee
31
33
import os
 
34
import re
32
35
from StringIO import StringIO
33
36
import string
34
37
import sys
293
296
def utc_now():
294
297
    """Return a timezone-aware timestamp for the current time."""
295
298
    return datetime.now(tz=pytz.UTC)
 
299
 
 
300
 
 
301
# This is a regular expression that matches email address embedded in
 
302
# text. It is not RFC 2821 compliant, nor does it need to be. This
 
303
# expression strives to identify probable email addresses so that they
 
304
# can be obfuscated when viewed by unauthenticated users. See
 
305
# http://www.email-unlimited.com/stuff/email_address_validator.htm
 
306
 
 
307
# localnames do not have [&?%!@<>,;:`|{}()#*^~ ] in practice
 
308
# (regardless of RFC 2821) because they conflict with other systems.
 
309
# See https://lists.ubuntu.com
 
310
#     /mailman/private/launchpad-reviews/2007-June/006081.html
 
311
 
 
312
# This verson of the re is more than 5x faster that the orginal
 
313
# version used in ftest/test_tales.testObfuscateEmail.
 
314
re_email_address = re.compile(r"""
 
315
    \b[a-zA-Z0-9._/="'+-]{1,64}@  # The localname.
 
316
    [a-zA-Z][a-zA-Z0-9-]{1,63}    # The hostname.
 
317
    \.[a-zA-Z0-9.-]{1,251}\b      # Dot starts one or more domains.
 
318
    """, re.VERBOSE)              # ' <- font-lock turd
 
319
 
 
320
 
 
321
def obfuscate_email(text_to_obfuscate):
 
322
    """Obfuscate an email address.
 
323
 
 
324
    The email address is obfuscated as <email address hidden>.
 
325
 
 
326
    The pattern used to identify an email address is not 2822. It strives
 
327
    to match any possible email address embedded in the text. For example,
 
328
    mailto:person@domain.dom and http://person:password@domain.dom both
 
329
    match, though the http match is in fact not an email address.
 
330
    """
 
331
    text = re_email_address.sub(
 
332
        r'<email address hidden>', text_to_obfuscate)
 
333
    text = text.replace(
 
334
        "<<email address hidden>>", "<email address hidden>")
 
335
    return text