Пример #1
0
def watch_canary(sigid_base64):
    canary = get_canary(sigid_base64)
    if canary is None:
        return page_not_found('canary')

    if request.method == 'GET':
        return dict(canary=canary)

    if request.method == 'POST':
        try:
            email = request.form['email']
        except KeyError:
            flash(err_messages['incomplete_form'], 'error')
            return dict(canary=canary)
        except Exception as e:
            flash(err_messages['generic'], 'error')
            app.logger.error(e)
            return dict(canary=canary)

        if not re.search('@', email) or len(email) > 254:
            flash(err_messages['invalid_email'], 'error')
            return dict(canary=canary)

        alerts = request.form.getlist('alerts')
        on_publish = 'onPublish' in alerts
        on_overdue = 'onOverdue' in alerts
        # on_delete = list['onDelete']

        delay_days = 0
        if on_overdue:
            delay = int(request.form['delay'])
            delay_type = request.form['delayType']

            if not delay or not delay_type:
                on_overdue = False
            
            allowed_delays = 'day', 'week', 'month'
            in_range = 1 <= delay <= 100

            if delay_type not in allowed_delays or not in_range:
                flash(err_messages['incomplete_form'], 'error')
                return dict(canary=canary)
            # Get the delay in days
            delay_days = days(delay, delay_type)

        # TODO: notify watchers when an canary is deleted
        # on_delete = request.form.get('onDelete') or False
        if not (on_publish or on_overdue):
            flash(err_messages['incomplete_form'], 'error')
            return dict(canary=canary)

        secret = os.urandom(16).encode('hex')
        alert = Alert(email, canary, False, on_overdue, on_publish,
                      delay_days, secret)
        db_session.add(alert)
        db_session.commit()

        # Send verification email
        send_verification_email.delay(alert, canary)
        return redirect(url_for('canary', sigid_base64=sigid_base64))
Пример #2
0
def edit_canary(sigid_base64):
    if not logged_in():
        return redirect(url_for('login'))

    canary = get_canary(sigid_base64)
    if canary is None:
        return page_not_found('canary')
    if logged_in and canary.user.fingerprint == session['fp']:
        freq_num = request.form['frequencyNum']
        freq = request.form['frequency']
        canary.freq_type = freq
        canary.frequency = days(freq_num, freq)
        canary.active = True
        db_session.commit()
        flash(messages['canary_updated'], 'message')
        return redirect(url_for('canary', sigid_base64=sigid_base64))
    else:
        abort(403)
Пример #3
0
def new_canary():
    if request.method == 'GET':
        return None

    if request.method == 'POST':
        try:
            signed = request.form['signedMessage']
            frequency_num = int(request.form['frequencyNum'])
            frequency_type = request.form['frequency']
        except KeyError:
            flash(err_messages['incomplete_form'], 'error')
            return None

        allowed_freqs = 'day', 'week', 'month'
        in_range = 1 <= frequency_num <= 100
        if frequency_type not in allowed_freqs or not in_range:
            flash(err_messages['invalid_freq'], 'error')
            return None
        # Get the frequency in days
        frequency = days(frequency_num, frequency_type)

        verified, err = gpg.verify(signed)
        # Start over if the message wasn't verified.
        if err and not verified:
            flash(err, 'error')
            return None

        fp = verified.fingerprint
        sigid_base64 = base64.urlsafe_b64encode(verified.signature_id)

        try:
            canary = Canary(sigid_base64, frequency, frequency_type)
            db_session.add(canary)
            db_session.commit()
        except IntegrityError:
            # Throw an error if a canary with that sigid already exists
            db_session.rollback()
            db_session.flush()
            flash(err_messages['dupe_canary'], 'error')
            return redirect(url_for('new_canary'))
        except Exception as e:
            db_session.rollback()
            db_session.flush()
            app.logger.error(e)
            """An unexpected database error should not reveal any
               error details to the user."""
            flash(err_messages['generic'], 'error')
            return None

        ciphertext = Challenge.generate(canary, fp)
        # TODO: This is sloppy.
        session['canary'] = dict(fp=verified.fingerprint.lower(),
                                 text=signed,
                                 uid=verified.username,
                                 keyid=verified.key_id,
                                 sigid_base64=sigid_base64,
                                 frequency=frequency,
                                 freq_type=frequency_type,
                                 ciphertext=str(ciphertext))

        flash(messages['verified'], 'message')
        return dict(canary=session['canary'])