예제 #1
0
def setup_sl_domain() -> SLDomain:
    """Take the first SLDomain and set its can_use_subdomain=True"""
    sl_domain: SLDomain = SLDomain.first()
    sl_domain.can_use_subdomain = True
    Session.commit()

    return sl_domain
예제 #2
0
def update_setting():
    """
    Update user setting
    Input:
    - notification: bool
    - alias_generator: word|uuid
    - random_alias_default_domain: str
    """
    user = g.user
    data = request.get_json() or {}

    if "notification" in data:
        user.notification = data["notification"]

    if "alias_generator" in data:
        alias_generator = data["alias_generator"]
        if alias_generator not in ["word", "uuid"]:
            return jsonify(error="Invalid alias_generator"), 400

        if alias_generator == "word":
            user.alias_generator = AliasGeneratorEnum.word.value
        else:
            user.alias_generator = AliasGeneratorEnum.uuid.value

    if "sender_format" in data:
        sender_format = data["sender_format"]
        if not SenderFormatEnum.has_name(sender_format):
            return jsonify(error="Invalid sender_format"), 400

        user.sender_format = SenderFormatEnum.get_value(sender_format)

    if "random_alias_default_domain" in data:
        default_domain = data["random_alias_default_domain"]
        sl_domain: SLDomain = SLDomain.get_by(domain=default_domain)
        if sl_domain:
            if sl_domain.premium_only and not user.is_premium():
                return jsonify(error="You cannot use this domain"), 400

            # make sure only default_random_alias_domain_id or default_random_alias_public_domain_id is set
            user.default_random_alias_public_domain_id = sl_domain.id
            user.default_random_alias_domain_id = None
        else:
            custom_domain = CustomDomain.get_by(domain=default_domain)
            if not custom_domain:
                return jsonify(error="invalid domain"), 400

            # sanity check
            if custom_domain.user_id != user.id or not custom_domain.verified:
                LOG.exception("%s cannot use domain %s", user, default_domain)
                return jsonify(error="invalid domain"), 400
            else:
                # make sure only default_random_alias_domain_id or
                # default_random_alias_public_domain_id is set
                user.default_random_alias_domain_id = custom_domain.id
                user.default_random_alias_public_domain_id = None

    db.session.commit()
    return jsonify(setting_to_dict(user))
예제 #3
0
def should_add_dkim_signature(domain: str) -> bool:
    if SLDomain.get_by(domain=domain):
        return True

    custom_domain: CustomDomain = CustomDomain.get_by(domain=domain)
    if custom_domain.dkim_verified:
        return True

    return False
예제 #4
0
def is_valid_alias_address_domain(address) -> bool:
    """Return whether an address domain might a domain handled by SimpleLogin"""
    domain = get_email_domain_part(address)
    if SLDomain.get_by(domain=domain):
        return True

    if CustomDomain.get_by(domain=domain, verified=True):
        return True

    return False
예제 #5
0
def migrate_domain_trash():
    """Move aliases from global trash to domain trash if applicable"""

    # ignore duplicate when insert
    # copied from https://github.com/sqlalchemy/sqlalchemy/issues/5374
    @compiles(Insert, "postgresql")
    def postgresql_on_conflict_do_nothing(insert, compiler, **kw):
        statement = compiler.visit_insert(insert, **kw)
        # IF we have a "RETURNING" clause, we must insert before it
        returning_position = statement.find("RETURNING")
        if returning_position >= 0:
            return (statement[:returning_position] +
                    "ON CONFLICT DO NOTHING " + statement[returning_position:])
        else:
            return statement + " ON CONFLICT DO NOTHING"

    sl_domains = [sl.domain for sl in SLDomain.all()]
    count = 0
    domain_deleted_aliases = []
    deleted_alias_ids = []
    for deleted_alias in DeletedAlias.yield_per_query():
        if count % 1000 == 0:
            LOG.d("process %s", count)

        count += 1

        alias_domain = get_email_domain_part(deleted_alias.email)
        if alias_domain not in sl_domains:
            custom_domain = CustomDomain.get_by(domain=alias_domain)
            if custom_domain:
                LOG.w("move %s to domain %s trash", deleted_alias,
                      custom_domain)
                domain_deleted_aliases.append(
                    DomainDeletedAlias(
                        user_id=custom_domain.user_id,
                        email=deleted_alias.email,
                        domain_id=custom_domain.id,
                        created_at=deleted_alias.created_at,
                    ))
                deleted_alias_ids.append(deleted_alias.id)

    LOG.d("create %s DomainDeletedAlias", len(domain_deleted_aliases))
    Session.bulk_save_objects(domain_deleted_aliases)

    LOG.d("delete %s DeletedAlias", len(deleted_alias_ids))
    DeletedAlias.filter(DeletedAlias.id.in_(deleted_alias_ids)).delete(
        synchronize_session=False)

    Session.commit()
예제 #6
0
def email_can_be_used_as_mailbox(email_address: str) -> bool:
    """Return True if an email can be used as a personal email.
    Use the email domain as criteria. A domain can be used if it is not:
    - one of ALIAS_DOMAINS
    - one of PREMIUM_ALIAS_DOMAINS
    - one of custom domains
    - a disposable domain
    """
    try:
        domain = validate_email(email_address,
                                check_deliverability=False,
                                allow_smtputf8=False).domain
    except EmailNotValidError:
        LOG.d("%s is invalid email address", email_address)
        return False

    if not domain:
        LOG.d("no valid domain associated to %s", email_address)
        return False

    if SLDomain.get_by(domain=domain):
        LOG.d("%s is a SL domain", email_address)
        return False

    from app.models import CustomDomain

    if CustomDomain.get_by(domain=domain, verified=True):
        LOG.d("domain %s is a SimpleLogin custom domain", domain)
        return False

    if is_invalid_mailbox_domain(domain):
        LOG.d("Domain %s is invalid mailbox domain", domain)
        return False

    # check if email MX domain is disposable
    mx_domains = get_mx_domain_list(domain)

    # if no MX record, email is not valid
    if not mx_domains:
        LOG.d("No MX record for domain %s", domain)
        return False

    for mx_domain in mx_domains:
        if is_invalid_mailbox_domain(mx_domain):
            LOG.d("MX Domain %s %s is invalid mailbox domain", mx_domain,
                  domain)
            return False

    return True
예제 #7
0
def set_custom_domain_for_alias():
    """Go through all aliases and make sure custom_domain is correctly set"""
    sl_domains = [sl_domain.domain for sl_domain in SLDomain.all()]
    for alias in Alias.yield_per_query().filter(
            Alias.custom_domain_id.is_(None)):
        if (not any(
                alias.email.endswith(f"@{sl_domain}")
                for sl_domain in sl_domains) and not alias.custom_domain_id):
            alias_domain = get_email_domain_part(alias.email)
            custom_domain = CustomDomain.get_by(domain=alias_domain)
            if custom_domain:
                LOG.e("set %s for %s", custom_domain, alias)
                alias.custom_domain_id = custom_domain.id
            else:  # phantom domain
                LOG.d("phantom domain %s %s %s", alias.user, alias,
                      alias.enabled)

    Session.commit()
예제 #8
0
def test_available_suffixes_default_domain(flask_client):
    user = login(flask_client)

    sl_domain = SLDomain.first()
    CustomDomain.create(user_id=user.id,
                        domain="test.com",
                        ownership_verified=True,
                        commit=True)

    user.default_alias_public_domain_id = sl_domain.id

    # first suffix is SL Domain
    first_suffix = get_available_suffixes(user)[0]
    assert first_suffix.suffix.endswith(f"@{sl_domain.domain}")

    user.default_alias_public_domain_id = None
    # first suffix is custom domain
    first_suffix = get_available_suffixes(user)[0]
    assert first_suffix.suffix == "@test.com"
예제 #9
0
def migrate_domain_trash():
    """Move aliases from global trash to domain trash if applicable"""
    for deleted_alias in DeletedAlias.query.all():
        alias_domain = get_email_domain_part(deleted_alias.email)
        if not SLDomain.get_by(domain=alias_domain):
            custom_domain = CustomDomain.get_by(domain=alias_domain)
            if custom_domain:
                LOG.d("move %s to domain %s trash", deleted_alias,
                      custom_domain)
                db.session.add(
                    DomainDeletedAlias(
                        user_id=custom_domain.user_id,
                        email=deleted_alias.email,
                        domain_id=custom_domain.id,
                        created_at=deleted_alias.created_at,
                    ))
                DeletedAlias.delete(deleted_alias.id)

    db.session.commit()
예제 #10
0
def add_sl_domains():
    for alias_domain in ALIAS_DOMAINS:
        if SLDomain.get_by(domain=alias_domain):
            LOG.d("%s is already a SL domain", alias_domain)
        else:
            LOG.info("Add %s to SL domain", alias_domain)
            SLDomain.create(domain=alias_domain)

    for premium_domain in PREMIUM_ALIAS_DOMAINS:
        if SLDomain.get_by(domain=premium_domain):
            LOG.d("%s is already a SL domain", premium_domain)
        else:
            LOG.info("Add %s to SL domain", premium_domain)
            SLDomain.create(domain=premium_domain, premium_only=True)

    db.session.commit()
예제 #11
0
def email_can_be_used_as_mailbox(email: str) -> bool:
    """Return True if an email can be used as a personal email.
    Use the email domain as criteria. A domain can be used if it is not:
    - one of ALIAS_DOMAINS
    - one of PREMIUM_ALIAS_DOMAINS
    - one of custom domains
    - a disposable domain
    """
    domain = get_email_domain_part(email)
    if not domain:
        return False

    if SLDomain.get_by(domain=domain):
        return False

    from app.models import CustomDomain

    if CustomDomain.get_by(domain=domain, verified=True):
        LOG.d("domain %s is a SimpleLogin custom domain", domain)
        return False

    if is_disposable_domain(domain):
        LOG.d("Domain %s is disposable", domain)
        return False

    # check if email MX domain is disposable
    mx_domains = get_mx_domain_list(domain)

    # if no MX record, email is not valid
    if not mx_domains:
        LOG.d("No MX record for domain %s", domain)
        return False

    for mx_domain in mx_domains:
        if is_disposable_domain(mx_domain):
            LOG.d("MX Domain %s %s is disposable", mx_domain, domain)
            return False

    return True
예제 #12
0
def setting():
    form = SettingForm()
    promo_form = PromoCodeForm()
    change_email_form = ChangeEmailForm()

    email_change = EmailChange.get_by(user_id=current_user.id)
    if email_change:
        pending_email = email_change.new_email
    else:
        pending_email = None

    if request.method == "POST":
        if request.form.get("form-name") == "update-email":
            if change_email_form.validate():
                # whether user can proceed with the email update
                new_email_valid = True
                if (change_email_form.email.data.lower().strip() !=
                        current_user.email and not pending_email):
                    new_email = change_email_form.email.data.strip().lower()

                    # check if this email is not already used
                    if personal_email_already_used(new_email) or Alias.get_by(
                            email=new_email):
                        flash(f"Email {new_email} already used", "error")
                        new_email_valid = False
                    elif not email_can_be_used_as_mailbox(new_email):
                        flash(
                            "You cannot use this email address as your personal inbox.",
                            "error",
                        )
                        new_email_valid = False
                    # a pending email change with the same email exists from another user
                    elif EmailChange.get_by(new_email=new_email):
                        other_email_change: EmailChange = EmailChange.get_by(
                            new_email=new_email)
                        LOG.warning(
                            "Another user has a pending %s with the same email address. Current user:%s",
                            other_email_change,
                            current_user,
                        )

                        if other_email_change.is_expired():
                            LOG.d("delete the expired email change %s",
                                  other_email_change)
                            EmailChange.delete(other_email_change.id)
                            db.session.commit()
                        else:
                            flash(
                                "You cannot use this email address as your personal inbox.",
                                "error",
                            )
                            new_email_valid = False

                    if new_email_valid:
                        email_change = EmailChange.create(
                            user_id=current_user.id,
                            code=random_string(
                                60),  # todo: make sure the code is unique
                            new_email=new_email,
                        )
                        db.session.commit()
                        send_change_email_confirmation(current_user,
                                                       email_change)
                        flash(
                            "A confirmation email is on the way, please check your inbox",
                            "success",
                        )
                        return redirect(url_for("dashboard.setting"))
        if request.form.get("form-name") == "update-profile":
            if form.validate():
                profile_updated = False
                # update user info
                if form.name.data != current_user.name:
                    current_user.name = form.name.data
                    db.session.commit()
                    profile_updated = True

                if form.profile_picture.data:
                    file_path = random_string(30)
                    file = File.create(user_id=current_user.id, path=file_path)

                    s3.upload_from_bytesio(
                        file_path, BytesIO(form.profile_picture.data.read()))

                    db.session.flush()
                    LOG.d("upload file %s to s3", file)

                    current_user.profile_picture_id = file.id
                    db.session.commit()
                    profile_updated = True

                if profile_updated:
                    flash(f"Your profile has been updated", "success")
                    return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "change-password":
            flash(
                "You are going to receive an email containing instructions to change your password",
                "success",
            )
            send_reset_password_email(current_user)
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "notification-preference":
            choose = request.form.get("notification")
            if choose == "on":
                current_user.notification = True
            else:
                current_user.notification = False
            db.session.commit()
            flash("Your notification preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "delete-account":
            LOG.warning("Delete account %s", current_user)
            User.delete(current_user.id)
            db.session.commit()
            flash("Your account has been deleted", "success")
            logout_user()
            return redirect(url_for("auth.register"))

        elif request.form.get("form-name") == "change-alias-generator":
            scheme = int(request.form.get("alias-generator-scheme"))
            if AliasGeneratorEnum.has_value(scheme):
                current_user.alias_generator = scheme
                db.session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))

        elif request.form.get(
                "form-name") == "change-random-alias-default-domain":
            default_domain = request.form.get("random-alias-default-domain")

            if default_domain:
                sl_domain: SLDomain = SLDomain.get_by(domain=default_domain)
                if sl_domain:
                    if sl_domain.premium_only and not current_user.is_premium(
                    ):
                        flash("You cannot use this domain", "error")
                        return redirect(url_for("dashboard.setting"))

                    # make sure only default_random_alias_domain_id or default_random_alias_public_domain_id is set
                    current_user.default_random_alias_public_domain_id = sl_domain.id
                    current_user.default_random_alias_domain_id = None
                else:
                    custom_domain = CustomDomain.get_by(domain=default_domain)
                    if custom_domain:
                        # sanity check
                        if (custom_domain.user_id != current_user.id
                                or not custom_domain.verified):
                            LOG.exception("%s cannot use domain %s",
                                          current_user, default_domain)
                        else:
                            # make sure only default_random_alias_domain_id or
                            # default_random_alias_public_domain_id is set
                            current_user.default_random_alias_domain_id = (
                                custom_domain.id)
                            current_user.default_random_alias_public_domain_id = None

            else:
                current_user.default_random_alias_domain_id = None
                current_user.default_random_alias_public_domain_id = None

            db.session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "change-sender-format":
            sender_format = int(request.form.get("sender-format"))
            if SenderFormatEnum.has_value(sender_format):
                current_user.sender_format = sender_format
                db.session.commit()
                flash("Your sender format preference has been updated",
                      "success")
            db.session.commit()
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "replace-ra":
            choose = request.form.get("replace-ra")
            if choose == "on":
                current_user.replace_reverse_alias = True
            else:
                current_user.replace_reverse_alias = False
            db.session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "export-data":
            data = {
                "email": current_user.email,
                "name": current_user.name,
                "aliases": [],
                "apps": [],
                "custom_domains": [],
            }

            for alias in Alias.filter_by(
                    user_id=current_user.id).all():  # type: Alias
                data["aliases"].append(
                    dict(email=alias.email, enabled=alias.enabled))

            for custom_domain in CustomDomain.filter_by(
                    user_id=current_user.id).all():
                data["custom_domains"].append(custom_domain.domain)

            for app in Client.filter_by(
                    user_id=current_user.id):  # type: Client
                data["apps"].append(
                    dict(name=app.name,
                         home_url=app.home_url,
                         published=app.published))

            return Response(
                json.dumps(data),
                mimetype="text/json",
                headers={
                    "Content-Disposition": "attachment;filename=data.json"
                },
            )
        elif request.form.get("form-name") == "export-alias":
            data = [["alias", "note", "enabled"]]
            for alias in Alias.filter_by(
                    user_id=current_user.id).all():  # type: Alias
                data.append([alias.email, alias.note, alias.enabled])

            si = StringIO()
            cw = csv.writer(si)
            cw.writerows(data)
            output = make_response(si.getvalue())
            output.headers[
                "Content-Disposition"] = "attachment; filename=aliases.csv"
            output.headers["Content-type"] = "text/csv"
            return output

    manual_sub = ManualSubscription.get_by(user_id=current_user.id)
    return render_template(
        "dashboard/setting.html",
        form=form,
        PlanEnum=PlanEnum,
        SenderFormatEnum=SenderFormatEnum,
        promo_form=promo_form,
        change_email_form=change_email_form,
        pending_email=pending_email,
        AliasGeneratorEnum=AliasGeneratorEnum,
        manual_sub=manual_sub,
        FIRST_ALIAS_DOMAIN=FIRST_ALIAS_DOMAIN,
    )
예제 #13
0
def setting():
    form = SettingForm()
    promo_form = PromoCodeForm()
    change_email_form = ChangeEmailForm()

    email_change = EmailChange.get_by(user_id=current_user.id)
    if email_change:
        pending_email = email_change.new_email
    else:
        pending_email = None

    if request.method == "POST":
        if request.form.get("form-name") == "update-email":
            if change_email_form.validate():
                # whether user can proceed with the email update
                new_email_valid = True
                if (sanitize_email(change_email_form.email.data) !=
                        current_user.email and not pending_email):
                    new_email = sanitize_email(change_email_form.email.data)

                    # check if this email is not already used
                    if personal_email_already_used(new_email) or Alias.get_by(
                            email=new_email):
                        flash(f"Email {new_email} already used", "error")
                        new_email_valid = False
                    elif not email_can_be_used_as_mailbox(new_email):
                        flash(
                            "You cannot use this email address as your personal inbox.",
                            "error",
                        )
                        new_email_valid = False
                    # a pending email change with the same email exists from another user
                    elif EmailChange.get_by(new_email=new_email):
                        other_email_change: EmailChange = EmailChange.get_by(
                            new_email=new_email)
                        LOG.warning(
                            "Another user has a pending %s with the same email address. Current user:%s",
                            other_email_change,
                            current_user,
                        )

                        if other_email_change.is_expired():
                            LOG.d("delete the expired email change %s",
                                  other_email_change)
                            EmailChange.delete(other_email_change.id)
                            db.session.commit()
                        else:
                            flash(
                                "You cannot use this email address as your personal inbox.",
                                "error",
                            )
                            new_email_valid = False

                    if new_email_valid:
                        email_change = EmailChange.create(
                            user_id=current_user.id,
                            code=random_string(
                                60),  # todo: make sure the code is unique
                            new_email=new_email,
                        )
                        db.session.commit()
                        send_change_email_confirmation(current_user,
                                                       email_change)
                        flash(
                            "A confirmation email is on the way, please check your inbox",
                            "success",
                        )
                        return redirect(url_for("dashboard.setting"))
        if request.form.get("form-name") == "update-profile":
            if form.validate():
                profile_updated = False
                # update user info
                if form.name.data != current_user.name:
                    current_user.name = form.name.data
                    db.session.commit()
                    profile_updated = True

                if form.profile_picture.data:
                    file_path = random_string(30)
                    file = File.create(user_id=current_user.id, path=file_path)

                    s3.upload_from_bytesio(
                        file_path, BytesIO(form.profile_picture.data.read()))

                    db.session.flush()
                    LOG.d("upload file %s to s3", file)

                    current_user.profile_picture_id = file.id
                    db.session.commit()
                    profile_updated = True

                if profile_updated:
                    flash("Your profile has been updated", "success")
                    return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "change-password":
            flash(
                "You are going to receive an email containing instructions to change your password",
                "success",
            )
            send_reset_password_email(current_user)
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "notification-preference":
            choose = request.form.get("notification")
            if choose == "on":
                current_user.notification = True
            else:
                current_user.notification = False
            db.session.commit()
            flash("Your notification preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "delete-account":
            # Schedule delete account job
            LOG.warning("schedule delete account job for %s", current_user)
            Job.create(
                name=JOB_DELETE_ACCOUNT,
                payload={"user_id": current_user.id},
                run_at=arrow.now(),
                commit=True,
            )

            flash(
                "Your account deletion has been scheduled. "
                "You'll receive an email when the deletion is finished",
                "success",
            )
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "change-alias-generator":
            scheme = int(request.form.get("alias-generator-scheme"))
            if AliasGeneratorEnum.has_value(scheme):
                current_user.alias_generator = scheme
                db.session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))

        elif request.form.get(
                "form-name") == "change-random-alias-default-domain":
            default_domain = request.form.get("random-alias-default-domain")

            if default_domain:
                sl_domain: SLDomain = SLDomain.get_by(domain=default_domain)
                if sl_domain:
                    if sl_domain.premium_only and not current_user.is_premium(
                    ):
                        flash("You cannot use this domain", "error")
                        return redirect(url_for("dashboard.setting"))

                    current_user.default_alias_public_domain_id = sl_domain.id
                    current_user.default_alias_custom_domain_id = None
                else:
                    custom_domain = CustomDomain.get_by(domain=default_domain)
                    if custom_domain:
                        # sanity check
                        if (custom_domain.user_id != current_user.id
                                or not custom_domain.verified):
                            LOG.exception("%s cannot use domain %s",
                                          current_user, default_domain)
                        else:
                            current_user.default_alias_custom_domain_id = (
                                custom_domain.id)
                            current_user.default_alias_public_domain_id = None

            else:
                current_user.default_alias_custom_domain_id = None
                current_user.default_alias_public_domain_id = None

            db.session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "change-sender-format":
            sender_format = int(request.form.get("sender-format"))
            if SenderFormatEnum.has_value(sender_format):
                current_user.sender_format = sender_format
                current_user.sender_format_updated_at = arrow.now()
                db.session.commit()
                flash("Your sender format preference has been updated",
                      "success")
            db.session.commit()
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "replace-ra":
            choose = request.form.get("replace-ra")
            if choose == "on":
                current_user.replace_reverse_alias = True
            else:
                current_user.replace_reverse_alias = False
            db.session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "sender-in-ra":
            choose = request.form.get("enable")
            if choose == "on":
                current_user.include_sender_in_reverse_alias = True
            else:
                current_user.include_sender_in_reverse_alias = False
            db.session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "export-data":
            return redirect(url_for("api.export_data"))
        elif request.form.get("form-name") == "export-alias":
            return redirect(url_for("api.export_aliases"))

    manual_sub = ManualSubscription.get_by(user_id=current_user.id)
    apple_sub = AppleSubscription.get_by(user_id=current_user.id)
    coinbase_sub = CoinbaseSubscription.get_by(user_id=current_user.id)

    return render_template(
        "dashboard/setting.html",
        form=form,
        PlanEnum=PlanEnum,
        SenderFormatEnum=SenderFormatEnum,
        promo_form=promo_form,
        change_email_form=change_email_form,
        pending_email=pending_email,
        AliasGeneratorEnum=AliasGeneratorEnum,
        manual_sub=manual_sub,
        apple_sub=apple_sub,
        coinbase_sub=coinbase_sub,
        FIRST_ALIAS_DOMAIN=FIRST_ALIAS_DOMAIN,
    )
예제 #14
0
def subdomain_route():
    if not current_user.subdomain_is_available():
        flash("Unknown error, redirect to the home page", "error")
        return redirect(url_for("dashboard.index"))

    sl_domains = SLDomain.filter_by(can_use_subdomain=True).all()
    subdomains = CustomDomain.filter_by(
        user_id=current_user.id, is_sl_subdomain=True
    ).all()

    errors = {}

    if request.method == "POST":
        if request.form.get("form-name") == "create":
            if not current_user.is_premium():
                flash("Only premium plan can add subdomain", "warning")
                return redirect(request.url)

            if current_user.subdomain_quota <= 0:
                flash(
                    f"You can't create more than {MAX_NB_SUBDOMAIN} subdomains", "error"
                )
                return redirect(request.url)

            subdomain = request.form.get("subdomain").lower().strip()
            domain = request.form.get("domain").lower().strip()

            if len(subdomain) < 3:
                flash("Subdomain must have at least 3 characters", "error")
                return redirect(request.url)

            if re.fullmatch(_SUBDOMAIN_PATTERN, subdomain) is None:
                flash(
                    "Subdomain can only contain lowercase letters, numbers and dashes (-)",
                    "error",
                )
                return redirect(request.url)

            if subdomain.endswith("-"):
                flash("Subdomain can't end with dash (-)", "error")
                return redirect(request.url)

            if domain not in [sl_domain.domain for sl_domain in sl_domains]:
                LOG.e("Domain %s is tampered by %s", domain, current_user)
                flash("Unknown error, refresh the page", "error")
                return redirect(request.url)

            full_domain = f"{subdomain}.{domain}"

            if CustomDomain.get_by(domain=full_domain):
                flash(f"{full_domain} already used", "error")
            elif Mailbox.filter(
                Mailbox.verified.is_(True),
                Mailbox.email.endswith(f"@{full_domain}"),
            ).first():
                flash(f"{full_domain} already used in a SimpleLogin mailbox", "error")
            else:
                try:
                    new_custom_domain = CustomDomain.create(
                        is_sl_subdomain=True,
                        catch_all=True,  # by default catch-all is enabled
                        domain=full_domain,
                        user_id=current_user.id,
                        verified=True,
                        dkim_verified=False,  # wildcard DNS does not work for DKIM
                        spf_verified=True,
                        dmarc_verified=False,  # wildcard DNS does not work for DMARC
                        ownership_verified=True,
                        commit=True,
                    )
                except SubdomainInTrashError:
                    flash(
                        f"{full_domain} has been used before and cannot be reused",
                        "error",
                    )
                else:
                    flash(
                        f"New subdomain {new_custom_domain.domain} is created",
                        "success",
                    )

                    return redirect(
                        url_for(
                            "dashboard.domain_detail",
                            custom_domain_id=new_custom_domain.id,
                        )
                    )

    return render_template(
        "dashboard/subdomain.html",
        sl_domains=sl_domains,
        errors=errors,
        subdomains=subdomains,
    )
예제 #15
0
def custom_domain():
    custom_domains = CustomDomain.filter_by(user_id=current_user.id,
                                            is_sl_subdomain=False).all()
    mailboxes = current_user.mailboxes()
    new_custom_domain_form = NewCustomDomainForm()

    errors = {}

    if request.method == "POST":
        if request.form.get("form-name") == "create":
            if not current_user.is_premium():
                flash("Only premium plan can add custom domain", "warning")
                return redirect(url_for("dashboard.custom_domain"))

            if new_custom_domain_form.validate():
                new_domain = new_custom_domain_form.domain.data.lower().strip()

                if new_domain.startswith("http://"):
                    new_domain = new_domain[len("http://"):]

                if new_domain.startswith("https://"):
                    new_domain = new_domain[len("https://"):]

                if SLDomain.get_by(domain=new_domain):
                    flash("A custom domain cannot be a built-in domain.",
                          "error")
                elif CustomDomain.get_by(domain=new_domain):
                    flash(f"{new_domain} already used", "error")
                elif get_email_domain_part(current_user.email) == new_domain:
                    flash(
                        "You cannot add a domain that you are currently using for your personal email. "
                        "Please change your personal email to your real email",
                        "error",
                    )
                elif Mailbox.filter(
                        Mailbox.verified.is_(True),
                        Mailbox.email.endswith(f"@{new_domain}")).first():
                    flash(
                        f"{new_domain} already used in a SimpleLogin mailbox",
                        "error")
                else:
                    new_custom_domain = CustomDomain.create(
                        domain=new_domain, user_id=current_user.id)
                    # new domain has ownership verified if its parent has the ownership verified
                    for root_cd in current_user.custom_domains:
                        if (new_domain.endswith("." + root_cd.domain)
                                and root_cd.ownership_verified):
                            LOG.i(
                                "%s ownership verified thanks to %s",
                                new_custom_domain,
                                root_cd,
                            )
                            new_custom_domain.ownership_verified = True

                    Session.commit()

                    mailbox_ids = request.form.getlist("mailbox_ids")
                    if mailbox_ids:
                        # check if mailbox is not tempered with
                        mailboxes = []
                        for mailbox_id in mailbox_ids:
                            mailbox = Mailbox.get(mailbox_id)
                            if (not mailbox
                                    or mailbox.user_id != current_user.id
                                    or not mailbox.verified):
                                flash("Something went wrong, please retry",
                                      "warning")
                                return redirect(
                                    url_for("dashboard.custom_domain"))
                            mailboxes.append(mailbox)

                        for mailbox in mailboxes:
                            DomainMailbox.create(
                                domain_id=new_custom_domain.id,
                                mailbox_id=mailbox.id)

                        Session.commit()

                    flash(f"New domain {new_custom_domain.domain} is created",
                          "success")

                    return redirect(
                        url_for(
                            "dashboard.domain_detail_dns",
                            custom_domain_id=new_custom_domain.id,
                        ))

    return render_template(
        "dashboard/custom_domain.html",
        custom_domains=custom_domains,
        new_custom_domain_form=new_custom_domain_form,
        EMAIL_SERVERS_WITH_PRIORITY=EMAIL_SERVERS_WITH_PRIORITY,
        errors=errors,
        mailboxes=mailboxes,
    )
예제 #16
0
def custom_domain():
    custom_domains = CustomDomain.query.filter_by(user_id=current_user.id).all()
    mailboxes = current_user.mailboxes()
    new_custom_domain_form = NewCustomDomainForm()

    errors = {}

    if request.method == "POST":
        if request.form.get("form-name") == "create":
            if not current_user.is_premium():
                flash("Only premium plan can add custom domain", "warning")
                return redirect(url_for("dashboard.custom_domain"))

            if new_custom_domain_form.validate():
                new_domain = new_custom_domain_form.domain.data.lower().strip()

                if new_domain.startswith("http://"):
                    new_domain = new_domain[len("http://") :]

                if new_domain.startswith("https://"):
                    new_domain = new_domain[len("https://") :]

                if SLDomain.get_by(domain=new_domain):
                    flash("A custom domain cannot be a built-in domain.", "error")
                elif CustomDomain.get_by(domain=new_domain):
                    flash(f"{new_domain} already used", "warning")
                elif get_email_domain_part(current_user.email) == new_domain:
                    flash(
                        "You cannot add a domain that you are currently using for your personal email. "
                        "Please change your personal email to your real email",
                        "error",
                    )
                else:
                    new_custom_domain = CustomDomain.create(
                        domain=new_domain, user_id=current_user.id
                    )
                    db.session.commit()

                    mailbox_ids = request.form.getlist("mailbox_ids")
                    if mailbox_ids:
                        # check if mailbox is not tempered with
                        mailboxes = []
                        for mailbox_id in mailbox_ids:
                            mailbox = Mailbox.get(mailbox_id)
                            if (
                                not mailbox
                                or mailbox.user_id != current_user.id
                                or not mailbox.verified
                            ):
                                flash("Something went wrong, please retry", "warning")
                                return redirect(url_for("dashboard.custom_domain"))
                            mailboxes.append(mailbox)

                        for mailbox in mailboxes:
                            DomainMailbox.create(
                                domain_id=new_custom_domain.id, mailbox_id=mailbox.id
                            )

                        db.session.commit()

                    flash(
                        f"New domain {new_custom_domain.domain} is created", "success"
                    )

                    return redirect(
                        url_for(
                            "dashboard.domain_detail_dns",
                            custom_domain_id=new_custom_domain.id,
                        )
                    )
        elif request.form.get("form-name") == "update":
            domain_id = request.form.get("domain-id")
            domain = CustomDomain.get(domain_id)

            if not domain or domain.user_id != current_user.id:
                flash("Unknown error. Refresh the page", "warning")
                return redirect(url_for("dashboard.custom_domain"))

            mailbox_ids = request.form.getlist("mailbox_ids")
            # check if mailbox is not tempered with
            mailboxes = []
            for mailbox_id in mailbox_ids:
                mailbox = Mailbox.get(mailbox_id)
                if (
                    not mailbox
                    or mailbox.user_id != current_user.id
                    or not mailbox.verified
                ):
                    flash("Something went wrong, please retry", "warning")
                    return redirect(url_for("dashboard.custom_domain"))
                mailboxes.append(mailbox)

            if not mailboxes:
                flash("You must select at least 1 mailbox", "warning")
                return redirect(url_for("dashboard.custom_domain"))

            # first remove all existing domain-mailboxes links
            DomainMailbox.query.filter_by(domain_id=domain.id).delete()
            db.session.flush()

            for mailbox in mailboxes:
                DomainMailbox.create(domain_id=domain.id, mailbox_id=mailbox.id)

            db.session.commit()
            flash(f"Domain {domain.domain} has been updated", "success")

            return redirect(url_for("dashboard.custom_domain"))

    return render_template(
        "dashboard/custom_domain.html",
        custom_domains=custom_domains,
        new_custom_domain_form=new_custom_domain_form,
        EMAIL_SERVERS_WITH_PRIORITY=EMAIL_SERVERS_WITH_PRIORITY,
        errors=errors,
        mailboxes=mailboxes,
    )
예제 #17
0
파일: server.py 프로젝트: ricocf/app
def fake_data():
    LOG.d("create fake data")
    # Remove db if exist
    if os.path.exists("db.sqlite"):
        LOG.d("remove existing db file")
        os.remove("db.sqlite")

    # Create all tables
    db.create_all()

    # Create a user
    user = User.create(
        email="*****@*****.**",
        name="John Wick",
        password="******",
        activated=True,
        is_admin=True,
        # enable_otp=True,
        otp_secret="base32secret3232",
        intro_shown=True,
        fido_uuid=None,
    )
    user.trial_end = None
    db.session.commit()

    # add a profile picture
    file_path = "profile_pic.svg"
    s3.upload_from_bytesio(
        file_path,
        open(os.path.join(ROOT_DIR, "static", "default-icon.svg"), "rb"),
        content_type="image/svg",
    )
    file = File.create(user_id=user.id, path=file_path, commit=True)
    user.profile_picture_id = file.id
    db.session.commit()

    # create a bounced email
    alias = Alias.create_new_random(user)
    db.session.commit()

    bounce_email_file_path = "bounce.eml"
    s3.upload_email_from_bytesio(
        bounce_email_file_path,
        open(os.path.join(ROOT_DIR, "local_data", "email_tests", "2.eml"),
             "rb"),
        "download.eml",
    )
    refused_email = RefusedEmail.create(
        path=bounce_email_file_path,
        full_report_path=bounce_email_file_path,
        user_id=user.id,
        commit=True,
    )

    contact = Contact.create(
        user_id=user.id,
        alias_id=alias.id,
        website_email="*****@*****.**",
        reply_email="*****@*****.**",
        commit=True,
    )
    EmailLog.create(
        user_id=user.id,
        contact_id=contact.id,
        alias_id=contact.alias_id,
        refused_email_id=refused_email.id,
        bounced=True,
        commit=True,
    )

    LifetimeCoupon.create(code="lifetime-coupon", nb_used=10, commit=True)
    Coupon.create(code="coupon", commit=True)

    # Create a subscription for user
    Subscription.create(
        user_id=user.id,
        cancel_url="https://checkout.paddle.com/subscription/cancel?user=1234",
        update_url="https://checkout.paddle.com/subscription/update?user=1234",
        subscription_id="123",
        event_time=arrow.now(),
        next_bill_date=arrow.now().shift(days=10).date(),
        plan=PlanEnum.monthly,
        commit=True,
    )

    CoinbaseSubscription.create(user_id=user.id,
                                end_at=arrow.now().shift(days=10),
                                commit=True)

    api_key = ApiKey.create(user_id=user.id, name="Chrome")
    api_key.code = "code"

    api_key = ApiKey.create(user_id=user.id, name="Firefox")
    api_key.code = "codeFF"

    pgp_public_key = open(get_abs_path("local_data/public-pgp.asc")).read()
    m1 = Mailbox.create(
        user_id=user.id,
        email="*****@*****.**",
        verified=True,
        pgp_public_key=pgp_public_key,
    )
    m1.pgp_finger_print = load_public_key(pgp_public_key)
    db.session.commit()

    # [email protected] is in a LOT of data breaches
    Alias.create(email="*****@*****.**",
                 user_id=user.id,
                 mailbox_id=m1.id)

    for i in range(3):
        if i % 2 == 0:
            a = Alias.create(email=f"e{i}@{FIRST_ALIAS_DOMAIN}",
                             user_id=user.id,
                             mailbox_id=m1.id)
        else:
            a = Alias.create(
                email=f"e{i}@{FIRST_ALIAS_DOMAIN}",
                user_id=user.id,
                mailbox_id=user.default_mailbox_id,
            )
        db.session.commit()

        if i % 5 == 0:
            if i % 2 == 0:
                AliasMailbox.create(alias_id=a.id,
                                    mailbox_id=user.default_mailbox_id)
            else:
                AliasMailbox.create(alias_id=a.id, mailbox_id=m1.id)
        db.session.commit()

        # some aliases don't have any activity
        # if i % 3 != 0:
        #     contact = Contact.create(
        #         user_id=user.id,
        #         alias_id=a.id,
        #         website_email=f"contact{i}@example.com",
        #         reply_email=f"rep{i}@sl.local",
        #     )
        #     db.session.commit()
        #     for _ in range(3):
        #         EmailLog.create(user_id=user.id, contact_id=contact.id, alias_id=contact.alias_id)
        #         db.session.commit()

        # have some disabled alias
        if i % 5 == 0:
            a.enabled = False
            db.session.commit()

    custom_domain1 = CustomDomain.create(user_id=user.id,
                                         domain="ab.cd",
                                         verified=True)
    db.session.commit()

    Alias.create(
        user_id=user.id,
        email="*****@*****.**",
        mailbox_id=user.default_mailbox_id,
        custom_domain_id=custom_domain1.id,
        commit=True,
    )

    Alias.create(
        user_id=user.id,
        email="*****@*****.**",
        mailbox_id=user.default_mailbox_id,
        custom_domain_id=custom_domain1.id,
        commit=True,
    )

    Directory.create(user_id=user.id, name="abcd")
    Directory.create(user_id=user.id, name="xyzt")
    db.session.commit()

    # Create a client
    client1 = Client.create_new(name="Demo", user_id=user.id)
    client1.oauth_client_id = "client-id"
    client1.oauth_client_secret = "client-secret"
    db.session.commit()

    RedirectUri.create(client_id=client1.id,
                       uri="https://your-website.com/oauth-callback")

    client2 = Client.create_new(name="Demo 2", user_id=user.id)
    client2.oauth_client_id = "client-id2"
    client2.oauth_client_secret = "client-secret2"
    db.session.commit()

    ClientUser.create(user_id=user.id, client_id=client1.id, name="Fake Name")

    referral = Referral.create(user_id=user.id,
                               code="Website",
                               name="First referral")
    Referral.create(user_id=user.id, code="Podcast", name="First referral")
    Payout.create(user_id=user.id,
                  amount=1000,
                  number_upgraded_account=100,
                  payment_method="BTC")
    Payout.create(
        user_id=user.id,
        amount=5000,
        number_upgraded_account=200,
        payment_method="PayPal",
    )
    db.session.commit()

    for i in range(6):
        Notification.create(user_id=user.id,
                            message=f"""Hey hey <b>{i}</b> """ * 10)
    db.session.commit()

    user2 = User.create(
        email="*****@*****.**",
        password="******",
        activated=True,
        referral_id=referral.id,
    )
    Mailbox.create(user_id=user2.id,
                   email="*****@*****.**",
                   verified=True)
    db.session.commit()

    ManualSubscription.create(
        user_id=user2.id,
        end_at=arrow.now().shift(years=1, days=1),
        comment="Local manual",
        commit=True,
    )

    SLDomain.create(domain="premium.com", premium_only=True, commit=True)
예제 #18
0
def setting():
    form = SettingForm()
    promo_form = PromoCodeForm()
    change_email_form = ChangeEmailForm()

    email_change = EmailChange.get_by(user_id=current_user.id)
    if email_change:
        pending_email = email_change.new_email
    else:
        pending_email = None

    if request.method == "POST":
        if request.form.get("form-name") == "update-email":
            if change_email_form.validate():
                # whether user can proceed with the email update
                new_email_valid = True
                if (
                    sanitize_email(change_email_form.email.data) != current_user.email
                    and not pending_email
                ):
                    new_email = sanitize_email(change_email_form.email.data)

                    # check if this email is not already used
                    if personal_email_already_used(new_email) or Alias.get_by(
                        email=new_email
                    ):
                        flash(f"Email {new_email} already used", "error")
                        new_email_valid = False
                    elif not email_can_be_used_as_mailbox(new_email):
                        flash(
                            "You cannot use this email address as your personal inbox.",
                            "error",
                        )
                        new_email_valid = False
                    # a pending email change with the same email exists from another user
                    elif EmailChange.get_by(new_email=new_email):
                        other_email_change: EmailChange = EmailChange.get_by(
                            new_email=new_email
                        )
                        LOG.w(
                            "Another user has a pending %s with the same email address. Current user:%s",
                            other_email_change,
                            current_user,
                        )

                        if other_email_change.is_expired():
                            LOG.d(
                                "delete the expired email change %s", other_email_change
                            )
                            EmailChange.delete(other_email_change.id)
                            Session.commit()
                        else:
                            flash(
                                "You cannot use this email address as your personal inbox.",
                                "error",
                            )
                            new_email_valid = False

                    if new_email_valid:
                        email_change = EmailChange.create(
                            user_id=current_user.id,
                            code=random_string(
                                60
                            ),  # todo: make sure the code is unique
                            new_email=new_email,
                        )
                        Session.commit()
                        send_change_email_confirmation(current_user, email_change)
                        flash(
                            "A confirmation email is on the way, please check your inbox",
                            "success",
                        )
                        return redirect(url_for("dashboard.setting"))
        if request.form.get("form-name") == "update-profile":
            if form.validate():
                profile_updated = False
                # update user info
                if form.name.data != current_user.name:
                    current_user.name = form.name.data
                    Session.commit()
                    profile_updated = True

                if form.profile_picture.data:
                    file_path = random_string(30)
                    file = File.create(user_id=current_user.id, path=file_path)

                    s3.upload_from_bytesio(
                        file_path, BytesIO(form.profile_picture.data.read())
                    )

                    Session.flush()
                    LOG.d("upload file %s to s3", file)

                    current_user.profile_picture_id = file.id
                    Session.commit()
                    profile_updated = True

                if profile_updated:
                    flash("Your profile has been updated", "success")
                    return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "change-password":
            flash(
                "You are going to receive an email containing instructions to change your password",
                "success",
            )
            send_reset_password_email(current_user)
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "notification-preference":
            choose = request.form.get("notification")
            if choose == "on":
                current_user.notification = True
            else:
                current_user.notification = False
            Session.commit()
            flash("Your notification preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "change-alias-generator":
            scheme = int(request.form.get("alias-generator-scheme"))
            if AliasGeneratorEnum.has_value(scheme):
                current_user.alias_generator = scheme
                Session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "change-random-alias-default-domain":
            default_domain = request.form.get("random-alias-default-domain")

            if default_domain:
                sl_domain: SLDomain = SLDomain.get_by(domain=default_domain)
                if sl_domain:
                    if sl_domain.premium_only and not current_user.is_premium():
                        flash("You cannot use this domain", "error")
                        return redirect(url_for("dashboard.setting"))

                    current_user.default_alias_public_domain_id = sl_domain.id
                    current_user.default_alias_custom_domain_id = None
                else:
                    custom_domain = CustomDomain.get_by(domain=default_domain)
                    if custom_domain:
                        # sanity check
                        if (
                            custom_domain.user_id != current_user.id
                            or not custom_domain.verified
                        ):
                            LOG.w(
                                "%s cannot use domain %s", current_user, custom_domain
                            )
                            flash(f"Domain {default_domain} can't be used", "error")
                            return redirect(request.url)
                        else:
                            current_user.default_alias_custom_domain_id = (
                                custom_domain.id
                            )
                            current_user.default_alias_public_domain_id = None

            else:
                current_user.default_alias_custom_domain_id = None
                current_user.default_alias_public_domain_id = None

            Session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "random-alias-suffix":
            scheme = int(request.form.get("random-alias-suffix-generator"))
            if AliasSuffixEnum.has_value(scheme):
                current_user.random_alias_suffix = scheme
                Session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "change-sender-format":
            sender_format = int(request.form.get("sender-format"))
            if SenderFormatEnum.has_value(sender_format):
                current_user.sender_format = sender_format
                current_user.sender_format_updated_at = arrow.now()
                Session.commit()
                flash("Your sender format preference has been updated", "success")
            Session.commit()
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "replace-ra":
            choose = request.form.get("replace-ra")
            if choose == "on":
                current_user.replace_reverse_alias = True
            else:
                current_user.replace_reverse_alias = False
            Session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "sender-in-ra":
            choose = request.form.get("enable")
            if choose == "on":
                current_user.include_sender_in_reverse_alias = True
            else:
                current_user.include_sender_in_reverse_alias = False
            Session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))

        elif request.form.get("form-name") == "expand-alias-info":
            choose = request.form.get("enable")
            if choose == "on":
                current_user.expand_alias_info = True
            else:
                current_user.expand_alias_info = False
            Session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))
        elif request.form.get("form-name") == "ignore-loop-email":
            choose = request.form.get("enable")
            if choose == "on":
                current_user.ignore_loop_email = True
            else:
                current_user.ignore_loop_email = False
            Session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))
        elif request.form.get("form-name") == "one-click-unsubscribe":
            choose = request.form.get("enable")
            if choose == "on":
                current_user.one_click_unsubscribe_block_sender = True
            else:
                current_user.one_click_unsubscribe_block_sender = False
            Session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))
        elif request.form.get("form-name") == "include_website_in_one_click_alias":
            choose = request.form.get("enable")
            if choose == "on":
                current_user.include_website_in_one_click_alias = True
            else:
                current_user.include_website_in_one_click_alias = False
            Session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))
        elif request.form.get("form-name") == "change-blocked-behaviour":
            choose = request.form.get("blocked-behaviour")
            if choose == str(BlockBehaviourEnum.return_2xx.value):
                current_user.block_behaviour = BlockBehaviourEnum.return_2xx.name
            elif choose == str(BlockBehaviourEnum.return_5xx.value):
                current_user.block_behaviour = BlockBehaviourEnum.return_5xx.name
            else:
                flash("There was an error. Please try again", "warning")
                return redirect(url_for("dashboard.setting"))
            Session.commit()
            flash("Your preference has been updated", "success")
        elif request.form.get("form-name") == "sender-header":
            choose = request.form.get("enable")
            if choose == "on":
                current_user.include_header_email_header = True
            else:
                current_user.include_header_email_header = False
            Session.commit()
            flash("Your preference has been updated", "success")
            return redirect(url_for("dashboard.setting"))
        elif request.form.get("form-name") == "export-data":
            return redirect(url_for("api.export_data"))
        elif request.form.get("form-name") == "export-alias":
            return redirect(url_for("api.export_aliases"))

    manual_sub = ManualSubscription.get_by(user_id=current_user.id)
    apple_sub = AppleSubscription.get_by(user_id=current_user.id)
    coinbase_sub = CoinbaseSubscription.get_by(user_id=current_user.id)

    return render_template(
        "dashboard/setting.html",
        form=form,
        PlanEnum=PlanEnum,
        SenderFormatEnum=SenderFormatEnum,
        BlockBehaviourEnum=BlockBehaviourEnum,
        promo_form=promo_form,
        change_email_form=change_email_form,
        pending_email=pending_email,
        AliasGeneratorEnum=AliasGeneratorEnum,
        manual_sub=manual_sub,
        apple_sub=apple_sub,
        coinbase_sub=coinbase_sub,
        FIRST_ALIAS_DOMAIN=FIRST_ALIAS_DOMAIN,
        ALIAS_RAND_SUFFIX_LENGTH=ALIAS_RANDOM_SUFFIX_LENGTH,
    )
예제 #19
0
def fake_data():
    LOG.d("create fake data")
    # Remove db if exist
    if os.path.exists("db.sqlite"):
        LOG.d("remove existing db file")
        os.remove("db.sqlite")

    # Create all tables
    db.create_all()

    # Create a user
    user = User.create(
        email="*****@*****.**",
        name="John Wick",
        password="******",
        activated=True,
        is_admin=True,
        enable_otp=False,
        otp_secret="base32secret3232",
        intro_shown=True,
        fido_uuid=None,
    )
    db.session.commit()

    user.trial_end = None

    LifetimeCoupon.create(code="coupon", nb_used=10)
    db.session.commit()

    # Create a subscription for user
    Subscription.create(
        user_id=user.id,
        cancel_url="https://checkout.paddle.com/subscription/cancel?user=1234",
        update_url="https://checkout.paddle.com/subscription/update?user=1234",
        subscription_id="123",
        event_time=arrow.now(),
        next_bill_date=arrow.now().shift(days=10).date(),
        plan=PlanEnum.monthly,
    )
    db.session.commit()

    api_key = ApiKey.create(user_id=user.id, name="Chrome")
    api_key.code = "code"

    api_key = ApiKey.create(user_id=user.id, name="Firefox")
    api_key.code = "codeFF"

    m1 = Mailbox.create(
        user_id=user.id,
        email="*****@*****.**",
        verified=True,
        pgp_finger_print="fake fingerprint",
    )
    db.session.commit()

    for i in range(3):
        if i % 2 == 0:
            a = Alias.create(email=f"e{i}@{FIRST_ALIAS_DOMAIN}",
                             user_id=user.id,
                             mailbox_id=m1.id)
        else:
            a = Alias.create(
                email=f"e{i}@{FIRST_ALIAS_DOMAIN}",
                user_id=user.id,
                mailbox_id=user.default_mailbox_id,
            )
        db.session.commit()

        if i % 5 == 0:
            if i % 2 == 0:
                AliasMailbox.create(alias_id=a.id,
                                    mailbox_id=user.default_mailbox_id)
            else:
                AliasMailbox.create(alias_id=a.id, mailbox_id=m1.id)
        db.session.commit()

        # some aliases don't have any activity
        # if i % 3 != 0:
        #     contact = Contact.create(
        #         user_id=user.id,
        #         alias_id=a.id,
        #         website_email=f"contact{i}@example.com",
        #         reply_email=f"rep{i}@sl.local",
        #     )
        #     db.session.commit()
        #     for _ in range(3):
        #         EmailLog.create(user_id=user.id, contact_id=contact.id)
        #         db.session.commit()

        # have some disabled alias
        if i % 5 == 0:
            a.enabled = False
            db.session.commit()

    CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True)
    CustomDomain.create(user_id=user.id,
                        domain="very-long-domain.com.net.org",
                        verified=True)
    db.session.commit()

    Directory.create(user_id=user.id, name="abcd")
    Directory.create(user_id=user.id, name="xyzt")
    db.session.commit()

    # Create a client
    client1 = Client.create_new(name="Demo", user_id=user.id)
    client1.oauth_client_id = "client-id"
    client1.oauth_client_secret = "client-secret"
    client1.published = True
    db.session.commit()

    RedirectUri.create(client_id=client1.id, uri="https://ab.com")

    client2 = Client.create_new(name="Demo 2", user_id=user.id)
    client2.oauth_client_id = "client-id2"
    client2.oauth_client_secret = "client-secret2"
    client2.published = True
    db.session.commit()

    ClientUser.create(user_id=user.id, client_id=client1.id, name="Fake Name")

    referral = Referral.create(user_id=user.id,
                               code="REFCODE",
                               name="First referral")
    db.session.commit()

    for i in range(6):
        Notification.create(user_id=user.id,
                            message=f"""Hey hey <b>{i}</b> """ * 10)
    db.session.commit()

    User.create(
        email="*****@*****.**",
        name="Winston",
        password="******",
        activated=True,
        referral_id=referral.id,
    )
    db.session.commit()

    for d in ["d1.localhost", "d2.localhost"]:
        SLDomain.create(domain=d)
    db.session.commit()