示例#1
0
def send_user_signup_notification(user):
    """Send notification to admin about new signed up commercial user."""
    pairs_list_to_string = lambda pairs_list: '\n'.join([
        '%s: %s' % (pair[0], pair[1]) for pair in pairs_list
    ])
    send_mail(
        subject="[MetaBrainz] New commercial user signed up",
        text=pairs_list_to_string([
            ('Organization name', user.org_name),
            ('Description', user.org_desc),
            ('Contact name', user.contact_name),
            ('Contact email', user.contact_email),

            ('Website URL', user.website_url),
            ('Logo image URL', user.org_logo_url),
            ('API URL', user.api_url),

            ('Street', user.address_street),
            ('City', user.address_city),
            ('State', user.address_state),
            ('Postal code', user.address_postcode),
            ('Country', user.address_country),

            ('Tier', str(user.tier)),
            ('Payment method', user.payment_method),
            ('Amount pledged', '$%s' % str(user.amount_pledged)),

            ('Data usage description', user.data_usage_desc),
        ]),
        recipients=current_app.config['NOTIFICATION_RECIPIENTS'],
    )
示例#2
0
def send_user_signup_notification(user):
    """Send notification to admin about new signed up commercial user."""
    pairs_list_to_string = lambda pairs_list: '\n'.join(
        ['%s: %s' % (pair[0], pair[1]) for pair in pairs_list])
    send_mail(
        subject="[MetaBrainz] New commercial user signed up",
        text=pairs_list_to_string([
            ('Organization name', user.org_name),
            ('Description', user.org_desc),
            ('Contact name', user.contact_name),
            ('Contact email', user.contact_email),
            ('Website URL', user.website_url),
            ('Logo image URL', user.org_logo_url),
            ('API URL', user.api_url),
            ('Street', user.address_street),
            ('City', user.address_city),
            ('State', user.address_state),
            ('Postal code', user.address_postcode),
            ('Country', user.address_country),
            ('Tier', str(user.tier)),
            ('Amount pledged', '$%s' % str(user.amount_pledged)),
            ('Data usage description', user.data_usage_desc),
        ]),
        recipients=current_app.config['NOTIFICATION_RECIPIENTS'],
    )
示例#3
0
def signup_noncommercial():
    """Sign up endpoint for non-commercial users."""
    mb_username = session.fetch_data(SESSION_KEY_MB_USERNAME)
    if not mb_username:
        session.persist_data(**{
            SESSION_KEY_ACCOUNT_TYPE: ACCOUNT_TYPE_NONCOMMERCIAL,
        })
        return redirect(url_for(".signup"))
    mb_email = session.fetch_data(SESSION_KEY_MB_EMAIL)

    form = NonCommercialSignUpForm(default_email=mb_email)
    if form.validate_on_submit():
        new_user = User.add(
            is_commercial=False,
            musicbrainz_id=mb_username,
            contact_name=form.contact_name.data,
            contact_email=form.contact_email.data,
            data_usage_desc=form.usage_desc.data,
        )
        login_user(new_user)
        flash.success("Thanks for signing up!")
        send_mail(
            subject="[MetaBrainz] Sign up confirmation",
            text='Dear %s,\n\nThank you for signing up!\n\nYou can now generate '
                 'an access token for the MetaBrainz API on your profile page.'
                 % new_user.contact_name,
            recipients=[new_user.contact_email],
        )
        return redirect(url_for('.profile'))

    return render_template("users/signup-non-commercial.html", form=form)
示例#4
0
def send_user_signup_notification(user):
    """Send notification to admin about new signed up commercial user."""
    pairs_list_to_string = lambda pairs_list: "\n".join(["%s: %s" % (pair[0], pair[1]) for pair in pairs_list])
    send_mail(
        subject="[MetaBrainz] New commercial user signed up",
        text=pairs_list_to_string(
            [
                ("Organization name", user.org_name),
                ("Description", user.org_desc),
                ("Contact name", user.contact_name),
                ("Contact email", user.contact_email),
                ("Website URL", user.website_url),
                ("Logo image URL", user.org_logo_url),
                ("API URL", user.api_url),
                ("Street", user.address_street),
                ("City", user.address_city),
                ("State", user.address_state),
                ("Postal code", user.address_postcode),
                ("Country", user.address_country),
                ("Tier", str(user.tier)),
                ("Amount pledged", "$%s" % str(user.amount_pledged)),
                ("Data usage description", user.data_usage_desc),
            ]
        ),
        recipients=current_app.config["NOTIFICATION_RECIPIENTS"],
    )
示例#5
0
def signup_noncommercial():
    """Sign up endpoint for non-commercial users."""
    mb_username = session.fetch_data(SESSION_KEY_MB_USERNAME)
    if not mb_username:
        session.persist_data(**{
            SESSION_KEY_ACCOUNT_TYPE: ACCOUNT_TYPE_NONCOMMERCIAL,
        })
        return redirect(url_for(".signup"))
    mb_email = session.fetch_data(SESSION_KEY_MB_EMAIL)

    form = NonCommercialSignUpForm(default_email=mb_email)
    if form.validate_on_submit():
        # Checking if this user already exists
        new_user = User.get(musicbrainz_id=mb_username)
        if not new_user:
            new_user = User.add(
                is_commercial=False,
                musicbrainz_id=mb_username,
                contact_name=form.contact_name.data,
                contact_email=form.contact_email.data,
                data_usage_desc=form.usage_desc.data,
            )
        login_user(new_user)
        flash.success("Thanks for signing up!")
        send_mail(
            subject="[MetaBrainz] Sign up confirmation",
            text='Dear %s,\n\nThank you for signing up!\n\nYou can now generate '
                 'an access token for the MetaBrainz API on your profile page.'
                 % new_user.contact_name,
            recipients=[new_user.contact_email],
        )
        return redirect(url_for('.profile'))

    return render_template("users/signup-non-commercial.html", form=form)
示例#6
0
 def set_state(self, state):
     old_state = self.state
     self.state = state
     db.session.commit()
     if old_state != self.state:
         # TODO: Send additional info about new state.
         state_name = "ACTIVE" if self.state == STATE_ACTIVE else \
                      "REJECTED" if self.state == STATE_REJECTED else \
                      "PENDING" if self.state == STATE_PENDING else \
                      self.state
         send_mail(
             subject="[MetaBrainz] Your account has been updated",
             text='State of your MetaBrainz account has been changed to "%s".' % state_name,
             recipients=[self.contact_email],
         )
示例#7
0
 def set_state(self, state):
     old_state = self.state
     self.state = state
     db.session.commit()
     if old_state != self.state:
         # TODO: Send additional info about new state.
         state_name = "ACTIVE" if self.state == STATE_ACTIVE else \
                      "REJECTED" if self.state == STATE_REJECTED else \
                      "PENDING" if self.state == STATE_PENDING else \
                      "WAITING" if self.state == STATE_WAITING else \
                      "LIMITED" if self.state == STATE_LIMITED else \
                      self.state
         send_mail(
             subject="[MetaBrainz] Your account has been updated",
             text='State of your MetaBrainz account has been changed to "%s".' % state_name,
             recipients=[self.contact_email],
         )
示例#8
0
    def create_record(cls, access_token, ip_address):
        """Creates new access log record with a current timestamp.

        It also checks if `DIFFERENT_IP_LIMIT` is exceeded within current time
        and `CLEANUP_RANGE_MINUTES`, alerts admins if that's the case.

        Args:
            access_token: Access token used to access the API.
            ip_address: IP access used to access the API.

        Returns:
            New access log record.
        """
        new_record = cls(
            token=access_token,
            ip_address=ip_address,
        )
        db.session.add(new_record)
        db.session.commit()

        cls.remove_old_ip_addr_records()

        # Checking if HOURLY_ALERT_THRESHOLD is exceeded
        count = cls.query \
            .distinct(cls.ip_address) \
            .filter(cls.timestamp > datetime.now(pytz.utc) - timedelta(minutes=CLEANUP_RANGE_MINUTES),
                    cls.token == access_token) \
            .count()
        if count > DIFFERENT_IP_LIMIT:
            msg = ("Hourly access threshold exceeded for token %s\n\n"
                   "This token has been used from %s different IP "
                   "addresses during the last %s minutes.") % \
                  (access_token, count, CLEANUP_RANGE_MINUTES)
            logging.info(msg)
            # Checking if notification for admins about this token abuse has
            # been sent in the last hour. This info is kept in memcached.
            key = "alert_sent_%s" % access_token
            if not cache.get(key):
                send_mail(
                    subject="[MetaBrainz] Hourly access threshold exceeded",
                    recipients=current_app.config['NOTIFICATION_RECIPIENTS'],
                    text=msg,
                )
                cache.set(key, True, 3600)  # 1 hour

        return new_record
示例#9
0
    def create_record(cls, access_token, ip_address):
        """Creates new access log record with a current timestamp.

        It also checks if `DIFFERENT_IP_LIMIT` is exceeded within current time
        and `CLEANUP_RANGE_MINUTES`, alerts admins if that's the case.

        Args:
            access_token: Access token used to access the API.
            ip_address: IP access used to access the API.

        Returns:
            New access log record.
        """
        new_record = cls(
            token=access_token,
            ip_address=ip_address,
        )
        db.session.add(new_record)
        db.session.commit()

        # Checking if HOURLY_ALERT_THRESHOLD is exceeded
        count = cls.query \
            .distinct(cls.ip_address) \
            .filter(cls.timestamp > datetime.now(pytz.utc) - timedelta(minutes=CLEANUP_RANGE_MINUTES),
                    cls.token == access_token) \
            .count()
        if count > DIFFERENT_IP_LIMIT:
            msg = ("Hourly access threshold exceeded for token %s\n\n"
                   "This token has been used from %s different IP "
                   "addresses during the last %s minutes.") % \
                  (access_token, count, CLEANUP_RANGE_MINUTES)
            logging.info(msg)
            # Checking if notification for admins about this token abuse has
            # been sent in the last hour. This info is kept in cache.
            key = "alert_sent_%s" % access_token
            if not cache.get(key):
                send_mail(
                    subject="[MetaBrainz] Hourly access threshold exceeded",
                    recipients=current_app.config['NOTIFICATION_RECIPIENTS'],
                    text=msg,
                )
                cache.set(key, True, 3600)  # 1 hour

        return new_record
示例#10
0
def send_receipt(email, date, amount, name, is_donation, editor_name=None):
    if is_donation:
        subject = "Receipt for your donation to the MetaBrainz Foundation"
        text = (
            "Dear %s:\n\n"
            "Thank you very much for your donation to the MetaBrainz Foundation!\n\n"
            "Your donation will allow the MetaBrainz Foundation to continue operating "
            "and improving the MusicBrainz project and its related projects. The "
            "foundation depends on donations from the community and therefore deeply "
            "appreciates your support.\n\n"
            "The MetaBrainz Foundation is a United States 501(c)(3) tax-exempt public "
            "charity. This allows US taxpayers to deduct this donation from their "
            "taxes under section 170 of the Internal Revenue Service code.\n\n"
            "Please save a printed copy of the attached PDF receipt for your records."
        ) % name
        from_addr = 'donations@' + current_app.config['MAIL_FROM_DOMAIN']
        from_name = 'Donation Manager'
        attachment_file_name = 'metabrainz_donation'
    else:
        subject = "Receipt for your payment to the MetaBrainz Foundation"
        text = (
            "Dear %s:\n\n"
            "Thank you very much for your payment to the MetaBrainz Foundation!\n\n"
            "Your payment will allow the MetaBrainz Foundation to continue operating "
            "and improving the MusicBrainz project and its related projects. The "
            "foundation depends on these payments and therefore deeply appreciates "
            "your support.\n\n"
            "Please save a printed copy of the attached PDF receipt for your records."
        ) % name
        from_addr = 'payments@' + current_app.config['MAIL_FROM_DOMAIN']
        from_name = 'Payment Manager'
        attachment_file_name = 'metabrainz_payment'

    send_mail(
        subject=subject,
        text=text,
        attachments=[(generate_recript(email, date, amount, name, is_donation,
                                       editor_name), 'pdf',
                      '%s.pdf' % attachment_file_name)],
        recipients=[email],
        from_addr=from_addr,
        from_name=from_name,
    )
示例#11
0
def signup_noncommercial():
    """Sign up endpoint for non-commercial users."""
    mb_username = session.fetch_data(SESSION_KEY_MB_USERNAME)
    if not mb_username:
        session.persist_data(**{
            SESSION_KEY_ACCOUNT_TYPE: ACCOUNT_TYPE_NONCOMMERCIAL,
        })
        return redirect(url_for(".signup"))
    mb_email = session.fetch_data(SESSION_KEY_MB_EMAIL)

    form = NonCommercialSignUpForm(default_email=mb_email)
    if form.validate_on_submit():
        # Checking if this user already exists
        new_user = User.get(musicbrainz_id=mb_username)
        if not new_user:
            new_user = User.add(
                is_commercial=False,
                musicbrainz_id=mb_username,
                contact_name=form.contact_name.data,
                contact_email=form.contact_email.data,
                data_usage_desc=form.usage_desc.data,
            )
            flash.success(gettext("Thanks for signing up!"))
            try:
                send_mail(
                    subject="[MetaBrainz] Sign up confirmation",
                    text='Dear %s,\n\nThank you for signing up!\n\nYou can now generate '
                         'an access token for the MetaBrainz API on your profile page.'
                         % new_user.contact_name,
                    recipients=[new_user.contact_email],
                )
            except MailException as e:
                logging.error(e)
                flash.warning(gettext(
                    "Failed to send welcome email to you. We are looking into it. "
                    "Sorry for inconvenience!"
                ))
        else:
            flash.info(gettext("You already have a MetaBrainz account!"))
        login_user(new_user)
        return redirect(url_for('.profile'))

    return render_template("users/signup-non-commercial.html", form=form, mb_username=mb_username)
示例#12
0
def send_receipt(email, date, amount, name, is_donation, editor_name=None):
    if is_donation:
        subject = "Receipt for your donation to the MetaBrainz Foundation"
        text = (
            "Dear %s:\n\n"
            "Thank you very much for your donation to the MetaBrainz Foundation!\n\n"
            "Your donation will allow the MetaBrainz Foundation to continue operating "
            "and improving the MusicBrainz project and its related projects. The "
            "foundation depends on donations from the community and therefore deeply "
            "appreciates your support.\n\n"
            "The MetaBrainz Foundation is a United States 501(c)(3) tax-exempt public "
            "charity. This allows US taxpayers to deduct this donation from their "
            "taxes under section 170 of the Internal Revenue Service code.\n\n"
            "Please save a printed copy of the attached PDF receipt for your records."
        ) % name
        from_addr = 'donations@' + current_app.config['MAIL_FROM_DOMAIN']
        from_name = 'Donation Manager'
        attachment_file_name = 'metabrainz_donation'
    else:
        subject = "Receipt for your payment to the MetaBrainz Foundation"
        text = (
            "Dear %s:\n\n"
            "Thank you very much for your payment to the MetaBrainz Foundation!\n\n"
            "Your payment will allow the MetaBrainz Foundation to continue operating "
            "and improving the MusicBrainz project and its related projects. The "
            "foundation depends on these payments and therefore deeply appreciates "
            "your support.\n\n"
            "Please save a printed copy of the attached PDF receipt for your records."
        ) % name
        from_addr = 'payments@' + current_app.config['MAIL_FROM_DOMAIN']
        from_name = 'Payment Manager'
        attachment_file_name = 'metabrainz_payment'

    send_mail(
        subject=subject,
        text=text,
        attachments=[(generate_recript(email, date, amount, name, is_donation, editor_name),
                      'pdf', '%s.pdf' % attachment_file_name)],
        recipients=[email],
        from_addr=from_addr,
        from_name=from_name,
    )
示例#13
0
def signup_commercial():
    """Sign up endpoint for commercial users.

    Commercial users need to choose support tier before filling out the form.
    `tier_id` argument with ID of a tier of choice is required there.
    """
    tier_id = request.args.get('tier_id')
    if not tier_id:
        flash.warn("You need to choose support tier before signing up!")
        return redirect(url_for('.account_type'))
    selected_tier = Tier.get(id=tier_id)
    if not selected_tier or not selected_tier.available:
        flash.error("You need to choose existing tier before signing up!")
        return redirect(url_for(".account_type"))

    mb_username = session.fetch_data(SESSION_KEY_MB_USERNAME)
    if not mb_username:
        session.persist_data(**{
            SESSION_KEY_ACCOUNT_TYPE: ACCOUNT_TYPE_COMMERCIAL,
            SESSION_KEY_TIER_ID: selected_tier.id,
        })
        return redirect(url_for(".signup"))
    mb_email = session.fetch_data(SESSION_KEY_MB_EMAIL)

    form = CommercialSignUpForm(default_email=mb_email)

    def custom_validation(f):
        if f.amount_pledged.data < selected_tier.price:
            flash.warning("Custom amount must be more than threshold amount"
                          "for selected tier or equal to it!")
            return False
        # Complete address is required if payment method is invoicing
        if f.payment_method.data == PAYMENT_METHOD_INVOICING:
            if not (form.address_street.data and
                    form.address_city.data and
                    form.address_state.data and
                    form.address_postcode.data and
                    form.address_country.data):
                flash.warning("You need to fill in all address fields if your "
                              "selected payment method is invoicing!")
                return False
        return True

    if form.validate_on_submit() and custom_validation(form):
        new_user = User.add(
            is_commercial=True,
            musicbrainz_id=mb_username,
            contact_name=form.contact_name.data,
            contact_email=form.contact_email.data,
            data_usage_desc=form.usage_desc.data,

            org_name=form.org_name.data,
            org_desc=form.org_desc.data,
            website_url=form.website_url.data,
            org_logo_url=form.logo_url.data,
            api_url=form.api_url.data,

            address_street=form.address_street.data,
            address_city=form.address_city.data,
            address_state=form.address_state.data,
            address_postcode=form.address_postcode.data,
            address_country=form.address_country.data,

            tier_id=tier_id,
            payment_method=form.payment_method.data,
            amount_pledged=form.amount_pledged.data,
        )
        login_user(new_user)
        flash.success("Thanks for signing up! Your application will be reviewed "
                      "soon. We will send you updates via email.")
        send_mail(
            subject="[MetaBrainz] Sign up confirmation",
            text="Dear %s,\n\nThank you for signing up!\n\nCurrently everyone is on "
                 "a summer vacation until July 14. Your application will be reviewed "
                 "as soon as we get back. We will send you updates via email. Sorry "
                 "for the inconvenience."
                 % new_user.contact_name,
            recipients=[new_user.contact_email],
        )
        return redirect(url_for('.profile'))

    return render_template("users/signup-commercial.html", form=form, tier=selected_tier)
示例#14
0
def signup_commercial():
    """Sign up endpoint for commercial users.

    Commercial users need to choose support tier before filling out the form.
    `tier_id` argument with ID of a tier of choice is required there.
    """
    tier_id = request.args.get('tier_id')
    if not tier_id:
        flash.warn("You need to choose support tier before signing up!")
        return redirect(url_for('.account_type'))
    selected_tier = Tier.get(id=tier_id)
    if not selected_tier or not selected_tier.available:
        flash.error("You need to choose existing tier before signing up!")
        return redirect(url_for(".account_type"))

    mb_username = session.fetch_data(SESSION_KEY_MB_USERNAME)
    if not mb_username:
        session.persist_data(**{
            SESSION_KEY_ACCOUNT_TYPE: ACCOUNT_TYPE_COMMERCIAL,
            SESSION_KEY_TIER_ID: selected_tier.id,
        })
        return redirect(url_for(".signup"))
    mb_email = session.fetch_data(SESSION_KEY_MB_EMAIL)

    form = CommercialSignUpForm(default_email=mb_email)

    def custom_validation(f):
        if f.amount_pledged.data < selected_tier.price:
            flash.warning("Custom amount must be more than threshold amount"
                          "for selected tier or equal to it!")
            return False
        return True

    if form.validate_on_submit() and custom_validation(form):
        # Checking if this user already exists
        new_user = User.get(musicbrainz_id=mb_username)
        if not new_user:
            new_user = User.add(
                is_commercial=True,
                musicbrainz_id=mb_username,
                contact_name=form.contact_name.data,
                contact_email=form.contact_email.data,
                data_usage_desc=form.usage_desc.data,

                org_name=form.org_name.data,
                org_desc=form.org_desc.data,
                website_url=form.website_url.data,
                org_logo_url=form.logo_url.data,
                api_url=form.api_url.data,

                address_street=form.address_street.data,
                address_city=form.address_city.data,
                address_state=form.address_state.data,
                address_postcode=form.address_postcode.data,
                address_country=form.address_country.data,

                tier_id=tier_id,
                amount_pledged=form.amount_pledged.data,
            )
            flash.success("Thanks for signing up! Your application will be reviewed "
                          "soon. We will send you updates via email.")
            send_mail(
                subject="[MetaBrainz] Sign up confirmation",
                text='Dear %s,\n\nThank you for signing up!\n\nYour application'
                     ' will be reviewed soon. We will send you updates via email.'
                     % new_user.contact_name,
                recipients=[new_user.contact_email],
            )
        else:
            flash.info("You already have a MetaBrainz account!")
        login_user(new_user)
        return redirect(url_for('.profile'))

    return render_template("users/signup-commercial.html", form=form, tier=selected_tier, mb_username=mb_username)
示例#15
0
def signup_commercial():
    """Sign up endpoint for commercial users.

    Commercial users need to choose support tier before filling out the form.
    `tier_id` argument with ID of a tier of choice is required there.
    """
    tier_id = request.args.get('tier_id')
    if not tier_id:
        flash.warn(
            gettext("You need to choose support tier before signing up!"))
        return redirect(url_for('.account_type'))
    selected_tier = Tier.get(id=tier_id)
    if not selected_tier or not selected_tier.available:
        flash.error(
            gettext("You need to choose existing tier before signing up!"))
        return redirect(url_for(".account_type"))

    mb_username = session.fetch_data(SESSION_KEY_MB_USERNAME)
    if not mb_username:
        session.persist_data(
            **{
                SESSION_KEY_ACCOUNT_TYPE: ACCOUNT_TYPE_COMMERCIAL,
                SESSION_KEY_TIER_ID: selected_tier.id,
            })
        return redirect(url_for(".signup"))
    mb_email = session.fetch_data(SESSION_KEY_MB_EMAIL)

    form = CommercialSignUpForm(default_email=mb_email)

    def custom_validation(f):
        if f.amount_pledged.data < selected_tier.price:
            flash.warning(
                gettext("Custom amount must be more than threshold amount"
                        "for selected tier or equal to it!"))
            return False
        return True

    if form.validate_on_submit() and custom_validation(form):
        # Checking if this user already exists
        new_user = User.get(musicbrainz_id=mb_username)
        if not new_user:
            new_user = User.add(
                is_commercial=True,
                musicbrainz_id=mb_username,
                contact_name=form.contact_name.data,
                contact_email=form.contact_email.data,
                data_usage_desc=form.usage_desc.data,
                org_name=form.org_name.data,
                org_desc=form.org_desc.data,
                website_url=form.website_url.data,
                org_logo_url=form.logo_url.data,
                api_url=form.api_url.data,
                address_street=form.address_street.data,
                address_city=form.address_city.data,
                address_state=form.address_state.data,
                address_postcode=form.address_postcode.data,
                address_country=form.address_country.data,
                tier_id=tier_id,
                amount_pledged=form.amount_pledged.data,
            )
            flash.success(
                gettext(
                    "Thanks for signing up! Your application will be reviewed "
                    "soon. We will send you updates via email."))
            try:
                send_mail(
                    subject="[MetaBrainz] Sign up confirmation",
                    text=
                    'Dear %s,\n\nThank you for signing up!\n\nYour application'
                    ' will be reviewed soon. We will send you updates via email.'
                    % new_user.contact_name,
                    recipients=[new_user.contact_email],
                )
            except MailException as e:
                logging.error(e)
                flash.warn(
                    gettext(
                        "Failed to send welcome email to you. We are looking into it. "
                        "Sorry for inconvenience!"))
        else:
            flash.info(gettext("You already have a MetaBrainz account!"))
        login_user(new_user)
        return redirect(url_for('.profile'))

    return render_template("users/signup-commercial.html",
                           form=form,
                           tier=selected_tier,
                           mb_username=mb_username)