def email_subscribe_pending_confirm(hexdomain): """Send a confirmation email for a user.""" domain = tools.parse_domain(hexdomain) if domain is None: flask.abort(400, 'Malformed domain or domain not represented in hexadecimal format.') email_address = flask.request.form['email_address'] if email_address.strip() == '': return flask.redirect('/email/subscribe/{}/0'.format(hexdomain)) verify_code = tools.random_id() verify_url = flask.request.url_root + 'email/verify/{}'.format(verify_code) email_body = email_tools.render_email( 'confirm.html', domain=domain, verify_url=verify_url ) repository.propose_subscription(verify_code, email_address, domain) emailer.send( email_address, 'Please verify your subscription', email_body ) return flask.render_template('www/email/pending_verify.html', domain=domain)
def test_generate_example_email_no_noisy(): """Email when no noisy domains.""" new = (('www.examp1e.com', '127.0.0.1'), ) updated = (('www.exampl3.com', '127.0.0.1', '127.0.0.2'), ) deleted = ( 'www.examplle.com', 'www.eeexamplez.com', 'wwwexample.com', ) noisy = set() delta_report = { 'new': new, 'updated': updated, 'deleted': deleted, } report = EmailReport(delta_report, noisy, include_noisy_domains=True) template = email_tools.render_email( 'report.html', domain='www.example.com', report=report, unsubscribe_link='https://dnstwister.report/...', ) with open('tests/manual/example_email_no_noisy.html', 'wb') as email_f: email_f.write(FORMATTING) email_f.write(template)
def send_email(domain, email_address, sub_id, report): """Format and send an email.""" body = email_tools.render_email( 'report.html', domain=domain, report=report, unsubscribe_link='https://dnstwister.report/email/unsubscribe/{}'. format(sub_id)) emailer.send(email_address, 'dnstwister report for {}'.format(domain), body) print 'Emailed delta for {} to {}'.format(domain, email_address)
def test_email_renderer_domain_sorting(): """Test the email rendering helper sorts domains.""" template = email_tools.render_email( 'report.html', domain='www.example.com', new=( ('www.examp2e.com', '', ''), ('www.examp1e.com', '', ''), ('www.examp2f.com', '', ''), ('www.axample.com', 'z', ''), ('www.axample.com', 'a', ''), ), updated=[], deleted=[], unsubscribe_link='https://dnstwister.report/...', ) assert template.strip() == textwrap.dedent(""" <h1>dnstwister report for 'www<span>.</span>example<span>.</span>com'</h1> <p> <a href="https://dnstwister.report/...">Unsubscribe</a> </p> <h2>New registrations</h2> <table> <thead> <tr> <th>Registered Domain</th> <th>Resolved IP</th> <th>Tools</th> </tr> </thead> <tbody> <tr> <td> www<span>.</span>axample<span>.</span>com </td> <td>a</td> <td><a href="">analyse</a></td> </tr> <tr> <td> www<span>.</span>axample<span>.</span>com </td> <td>z</td> <td><a href="">analyse</a></td> </tr> <tr> <td> www<span>.</span>examp1e<span>.</span>com </td> <td></td> <td><a href="">analyse</a></td> </tr> <tr> <td> www<span>.</span>examp2e<span>.</span>com </td> <td></td> <td><a href="">analyse</a></td> </tr> <tr> <td> www<span>.</span>examp2f<span>.</span>com </td> <td></td> <td><a href="">analyse</a></td> </tr> </tbody> </table> <p> <a href="https://dnstwister.report/...">Unsubscribe</a> </p> """).strip()
def test_email_renderer(): """Test the email rendering helper.""" template = email_tools.render_email( 'report.html', domain='www.example.com', new=(('www.examp1e.com', '127.0.0.1', 'http://dnstwister.report/analyse/1234'),), updated=(('www.exampl3.com', '127.0.0.1', '127.0.0.2', 'http://dnstwister.report/analyse/6789'),), deleted=('www.examplle.com',), noisy=('www.examplle.com',), unsubscribe_link='https://dnstwister.report/...', ) assert template.strip() == textwrap.dedent(""" <h1>dnstwister report for 'www<span>.</span>example<span>.</span>com'</h1> <p> <a href="https://dnstwister.report/...">Unsubscribe</a> </p> <h2>New registrations</h2> <table> <thead> <tr> <th>Registered Domain</th> <th>Resolved IP</th> <th>Tools</th> </tr> </thead> <tbody> <tr> <td> www<span>.</span>examp1e<span>.</span>com </td> <td>127.0.0.1</td> <td><a href="http://dnstwister.report/analyse/1234">analyse</a></td> </tr> </tbody> </table> <h2>Updated registrations</h2> <table> <thead> <tr> <th>Registered Domain</th> <th>Previously Resolved IP</th> <th>Currently Resolved IP</th> <th>Tools</th> </tr> </thead> <tbody> <tr> <td> www<span>.</span>exampl3<span>.</span>com </td> <td>127.0.0.1</td> <td>127.0.0.2</td> <td><a href="http://dnstwister.report/analyse/6789">analyse</a></td> </tr> </tbody> </table> <h2>Deleted registrations</h2> <table> <thead> <tr> <th>Previously Registered Domain</th> </tr> </thead> <tbody> <tr> <td> www<span>.</span>examplle<span>.</span>com * </td> </tr> </tbody> </table> <p> * "noisy" domain that changes state regularly. </p> <p> <a href="https://dnstwister.report/...">Unsubscribe</a> </p> """).strip()
def process_sub(sub_id, detail): """Process a subscription.""" domain = detail['domain'] email_address = detail['email_address'] # Ensure the domain is registered for reporting, register if not. repository.register_domain(domain) # Mark delta report as "read" so it's not unsubscribed. repository.mark_delta_report_as_read(domain) # Don't send more than once every 24 hours last_sent = repository.email_last_send_for_sub(sub_id) if last_sent is not None: age_last_sent = datetime.datetime.now() - last_sent if age_last_sent < datetime.timedelta(seconds=PERIOD): print 'Skipping {} + {}, < 24h hours'.format( email_address, domain ) return # Grab the delta delta = repository.get_delta_report(domain) if delta is None: print 'Skipping {} + {}, no delta report yet'.format( email_address, domain ) return # Grab the delta report update time. delta_updated = repository.delta_report_updated(domain) # If the delta report was updated > 23 hours ago, we're too close to the # next delta report. This means we should hold off so we don't send the # same delta report twice. if delta_updated is not None: age_delta_updated = datetime.datetime.now() - delta_updated if age_delta_updated > datetime.timedelta(hours=23): print 'Skipping {} + {}, delta > 23h hours old'.format( email_address, domain ) return # Don't email if no changes new = delta['new'] if len(delta['new']) > 0 else None updated = delta['updated'] if len(delta['updated']) > 0 else None deleted = delta['deleted'] if len(delta['deleted']) > 0 else None if new is updated is deleted is None: print 'Skipping {} + {}, no changes'.format( email_address, domain ) return # Add analysis links if new is not None: new = [(dom, ip, ANALYSIS_ROOT.format(binascii.hexlify(dom))) for (dom, ip) in new] if updated is not None: updated = [(dom, old_ip, new_ip, ANALYSIS_ROOT.format(binascii.hexlify(dom))) for (dom, old_ip, new_ip) in updated] # Email body = email_tools.render_email( 'report.html', domain=domain, new=new, updated=updated, deleted=deleted, unsubscribe_link='https://dnstwister.report/email/unsubscribe/{}'.format(sub_id) ) # Mark as emailed to ensure we don't flood if there's an error after the # actual email has been sent. repository.update_last_email_sub_sent_date(sub_id) emailer.send( email_address, 'dnstwister report for {}'.format(domain), body ) print 'Emailed delta for {} to {}'.format(domain, email_address)
def test_email_renderer(): """Test the email rendering helper.""" template = email_tools.render_email( 'report.html', domain='www.example.com', new=(('www.examp1e.com', '127.0.0.1', 'http://dnstwister.report/analyse/1234'),), updated=(('www.exampl3.com', '127.0.0.1', '127.0.0.2', 'http://dnstwister.report/analyse/6789'),), deleted=('www.examplle.com',), unsubscribe_link='https://dnstwister.report/...', noisy_link='https://dnstwister.report/email/1/noisy', ) assert template.strip() == textwrap.dedent(""" <h1>dnstwister report for <strong>www<span>.</span>example<span>.</span>com</strong></h1> <p> <a href="https://dnstwister.report/...">Unsubscribe</a> </p> <h2>New registrations</h2> <table> <thead> <tr> <th>Registered Domain</th> <th>Resolved IP</th> <th>Tools</th> </tr> </thead> <tbody> <tr> <td> www<span>.</span>examp1e<span>.</span>com </td> <td>127.0.0.1</td> <td><a href="http://dnstwister.report/analyse/1234">analyse</a></td> </tr> </tbody> </table> <h2>Updated registrations</h2> <table> <thead> <tr> <th>Registered Domain</th> <th>Previously Resolved IP</th> <th>Currently Resolved IP</th> <th>Tools</th> </tr> </thead> <tbody> <tr> <td> www<span>.</span>exampl3<span>.</span>com </td> <td>127.0.0.1</td> <td>127.0.0.2</td> <td><a href="http://dnstwister.report/analyse/6789">analyse</a></td> </tr> </tbody> </table> <h2>Deleted registrations</h2> <table> <thead> <tr> <th>Previously Registered Domain</th> </tr> </thead> <tbody> <tr> <td> www<span>.</span>examplle<span>.</span>com </td> </tr> </tbody> </table> <p> These emails <strong>exclude</strong> domains considered to be "noisy" - those that are either registered and unregistered constantly, or constantly change IP address. <a href="https://dnstwister.report/email/1/noisy">You can view a report of these domains at any time.</a> </p> <p> <a href="https://dnstwister.report/...">Unsubscribe</a> </p> """).strip()