Example #1
0
def format_message(message_type, recipients, *args):
    """Format a Message to be sent with the Mail module."""
    subject = mails[message_type][0]
    body = mails[message_type][1].format(*args)

    with app.app_context():
        return Message(subject, recipients, body)
Example #2
0
    def test_verify_watch_canary(self):
        """Test that visiting a verification page changes an Alert from
        unverified to verified.
        """
        c = self._create_canary()
        a = Alert(c.user.uid, c, True, True, True, 3, 'sekrit')
        db_session.add(a)
        db_session.commit()

        with app.app_context():
            r = self.app.get('verify/{}'.format(a.hash),
                follow_redirects=True)
            self.assertTrue(a.active)
            self.assertIn(messages['alert_verified'], r.data)
Example #3
0
def send_verification_email(alert, canary):
    """Send a verification email when someone signs up to watch a 
    canary."""
    if not app.testing:      
        alert = db_session.merge(alert)
        canary = db_session.merge(canary)

    verify_url = config.URL + '/verify/{}?canary={}?email={}'.format(
        alert.hash, canary.id, alert.email)
    canary_url = config.URL + '/canary/{}'.format(canary.sigid_base64)
    msg = format_message('verify_watch_canary', [alert.email],
                         canary_url, verify_url)
    with app.app_context():
        try:
            mail.send(msg)
        except SMTPException as e:
            app.logger.error(e)
Example #4
0
def notify(canary, user, text):
    """Send an email to notify ``user`` that ``canary`` was published
    with their key and to give them information about republishing
    ``canary``.
    """
    canary = db_session.merge(canary)
    user = db_session.merge(user)

    canary_url = config.URL + '/canary/{}'.format(canary.sigid_base64)
    msg = format_message('new_canary', [user.uid], user.keyid,
                         canary.frequency, canary.freq_type, canary_url,
                         text)

    with app.app_context():
        try:
            mail.send(msg)
        except SMTPException as e:
            app.logger.error(e)
Example #5
0
def send_overdue_alert(alert, canary, days_overdue):
    """Send a reminder to canary watchers the canary is overdue."""
    if days_overdue >= alert.delay:
        canary_url = config.URL + '/canary/{}'.format(
            canary.sigid_base64)

        msg = format_message('overdue_alert', [alert.email],
                             canary.user.uid, canary.user.uid,
                             days_overdue, canary_url)

        """Set active to False so we don't send another alert unless
        the canary owner republishes or deletes the canary."""
        alert.active = False
        db_session.commit()
        with app.app_context():
            try:
                mail.send(msg)
            except SMTPException as e:
                app.logger.error(e)
Example #6
0
def remind(canary, user):
    """Send an email to remind ``user`` to republish ``canary``.
    The email includes a link to a page with a challenge to decrypt.
    """
    if not app.testing:
        canary = db_session.merge(canary)
        user = db_session.merge(user)

    canary_url = config.URL + '/canary/{}'.format(canary.sigid_base64)
    msg = format_message('reminder', [user.uid], canary_url,
                         canary.frequency, canary.freq_type)

    """Set active to False so we don't send another reminder email
    unless the user republishes the canary."""
    canary.active = False
    db_session.commit()
    with app.app_context():
        try:
            mail.send(msg)
        except SMTPException as e:
            app.logger.error(e)
Example #7
0
def canary(sigid_base64):
    if request.method == 'GET':
        canary = get_canary(sigid_base64)
        if canary is None:
            return page_not_found('canary')

        pathstr = str(sigid_base64)
        path = os.path.join(app.config.get('CANARIES_DIR'), pathstr)
        f = open(path, 'r')
        text = f.read()
        f.close()
        return dict(canary=canary, text=text)

    if request.method == 'POST':
        if not is_sigid(sigid_base64):
            return redirect(url_for('index'))

        try:
            canary = Canary.query.filter(
                Canary.sigid_base64 == sigid_base64).one()
            decrypted = request.form['decrypted'].strip()
            if not Challenge.check(canary, decrypted):
                raise IncorrectChallengeException
        except KeyError:
            flash(err_messages['incomplete_form'], 'error')
            return None
        except IncorrectChallengeException:
            db_session.delete(canary)
            db_session.commit()
            flash(err_messages['decrypt_fail'], 'error')
            return redirect(url_for('new_canary'))
        except Exception as e:
            flash(err_messages['generic'], 'error')
            app.logger.error(e)
            return redirect(url_for('new_canary'))

        sess = session['canary']
        fp = sess['fp']
        try:
            user = User.query.filter(User.fingerprint == fp).one()
            """Update the existing user's key info, in case the username
            or email address has been edited since we last saw it."""
            user.update(canary['uid'])
        except NoResultFound:
            # Create a new user
            user = User(sess['keyid'], fp, sess['uid'])
            db_session.add(user)
            db_session.commit()

        canary.user_id = user.id
        canary.active = True
        db_session.commit()

        with app.app_context():
            text = sess['text']
            if app.testing:
                notify(canary, user, text)
            else:
                notify.delay(canary, user, text)

        pathstr = str(sigid_base64)
        path = os.path.join(app.config.get('CANARIES_DIR'), pathstr)

        with open(path, 'w') as f:
            f.write(text)
            f.close()

        flash(messages['published'], 'message')
        return redirect(url_for('canary', sigid_base64=sigid_base64))