def flask_client(): transaction = connection.begin() with app.app_context(): try: client = app.test_client() yield client finally: # roll back all commits made during a test transaction.rollback() Session.rollback() Session.close()
def delete_note(note_id): """Удалить заметку""" try: Session.query(Note).filter(Note.id == note_id).delete() Session.commit() return make_response(jsonify(success=True), 200) except: Session.rollback() raise return make_response(jsonify(success=True), 404)
def update_note(note_id): """Обновить заметку""" response = request.get_json() try: Session.query(Note).filter(Note.id == note_id).update( {"title": response["title"], "description": response["description"]} ) Session.commit() return make_response(jsonify(success=True), 202) except: Session.rollback() raise return make_response(jsonify(success=True), 404)
def add_note(): """Добавить новую заметку""" response = request.get_json() # validation if "id" in response and "title" in response and "description" in response: try: new_note = Note( id=response["id"], title=response["title"], description=response["description"], ) Session.add(new_note) Session.commit() return make_response(jsonify(success=True), 201) # Created except: Session.rollback() # raise return make_response(jsonify(success=False), 409) # Conflict else: return make_response(jsonify(success=False), 400) # Bad Request
def custom_alias(): # check if user has not exceeded the alias quota if not current_user.can_create_new_alias(): LOG.d("%s can't create new alias", current_user) flash( "You have reached free plan limit, please upgrade to create new aliases", "warning", ) return redirect(url_for("dashboard.index")) user_custom_domains = [ cd.domain for cd in current_user.verified_custom_domains() ] alias_suffixes = get_alias_suffixes(current_user) at_least_a_premium_domain = False for alias_suffix in alias_suffixes: if not alias_suffix.is_custom and alias_suffix.is_premium: at_least_a_premium_domain = True break alias_suffixes_with_signature = [ (alias_suffix, signer.sign(alias_suffix.serialize()).decode()) for alias_suffix in alias_suffixes ] mailboxes = current_user.mailboxes() if request.method == "POST": alias_prefix = request.form.get("prefix").strip().lower().replace( " ", "") signed_alias_suffix = request.form.get("signed-alias-suffix") mailbox_ids = request.form.getlist("mailboxes") alias_note = request.form.get("note") if not check_alias_prefix(alias_prefix): flash( "Only lowercase letters, numbers, dashes (-), dots (.) and underscores (_) " "are currently supported for alias prefix. Cannot be more than 40 letters", "error", ) return redirect(request.url) # 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(request.url) mailboxes.append(mailbox) if not mailboxes: flash("At least one mailbox must be selected", "error") return redirect(request.url) # hypothesis: user will click on the button in the 600 secs try: signed_alias_suffix_decoded = signer.unsign(signed_alias_suffix, max_age=600).decode() alias_suffix: AliasSuffix = AliasSuffix.deserialize( signed_alias_suffix_decoded) except SignatureExpired: LOG.w("Alias creation time expired for %s", current_user) flash("Alias creation time is expired, please retry", "warning") return redirect(request.url) except Exception: LOG.w("Alias suffix is tampered, user %s", current_user) flash("Unknown error, refresh the page", "error") return redirect(request.url) if verify_prefix_suffix(current_user, alias_prefix, alias_suffix.suffix): full_alias = alias_prefix + alias_suffix.suffix if ".." in full_alias: flash("Your alias can't contain 2 consecutive dots (..)", "error") return redirect(request.url) try: validate_email(full_alias, check_deliverability=False, allow_smtputf8=False) except EmailNotValidError as e: flash(str(e), "error") return redirect(request.url) general_error_msg = f"{full_alias} cannot be used" if Alias.get_by(email=full_alias): alias = Alias.get_by(email=full_alias) if alias.user_id == current_user.id: flash(f"You already have this alias {full_alias}", "error") else: flash(general_error_msg, "error") elif DomainDeletedAlias.get_by(email=full_alias): domain_deleted_alias: DomainDeletedAlias = DomainDeletedAlias.get_by( email=full_alias) custom_domain = domain_deleted_alias.domain if domain_deleted_alias.user_id == current_user.id: flash( f"You have deleted this alias before. You can restore it on " f"{custom_domain.domain} 'Deleted Alias' page", "error", ) else: # should never happen as user can only choose their domains LOG.e( "Deleted Alias %s does not belong to user %s", domain_deleted_alias, ) elif DeletedAlias.get_by(email=full_alias): flash(general_error_msg, "error") else: try: alias = Alias.create( user_id=current_user.id, email=full_alias, note=alias_note, mailbox_id=mailboxes[0].id, ) Session.flush() except IntegrityError: LOG.w("Alias %s already exists", full_alias) Session.rollback() flash("Unknown error, please retry", "error") return redirect(url_for("dashboard.custom_alias")) for i in range(1, len(mailboxes)): AliasMailbox.create( alias_id=alias.id, mailbox_id=mailboxes[i].id, ) Session.commit() flash(f"Alias {full_alias} has been created", "success") return redirect( url_for("dashboard.index", highlight_alias_id=alias.id)) # only happen if the request has been "hacked" else: flash("something went wrong", "warning") return render_template( "dashboard/custom_alias.html", user_custom_domains=user_custom_domains, alias_suffixes_with_signature=alias_suffixes_with_signature, at_least_a_premium_domain=at_least_a_premium_domain, mailboxes=mailboxes, )
def try_auto_create_directory(address: str) -> Optional[Alias]: """ Try to create an alias with directory """ # check if alias belongs to a directory, ie having directory/anything@EMAIL_DOMAIN format if can_create_directory_for_address(address): # if there's no directory separator in the alias, no way to auto-create it if "/" not in address and "+" not in address and "#" not in address: return None # alias contains one of the 3 special directory separator: "/", "+" or "#" if "/" in address: sep = "/" elif "+" in address: sep = "+" else: sep = "#" directory_name = address[:address.find(sep)] LOG.d("directory_name %s", directory_name) directory = Directory.get_by(name=directory_name) if not directory: return None user: User = directory.user if not user.can_create_new_alias(): send_cannot_create_directory_alias(user, address, directory_name) return None if directory.disabled: send_cannot_create_directory_alias_disabled( user, address, directory_name) return None try: LOG.d("create alias %s for directory %s", address, directory) mailboxes = directory.mailboxes alias = Alias.create( email=address, user_id=directory.user_id, directory_id=directory.id, mailbox_id=mailboxes[0].id, ) if not user.disable_automatic_alias_note: alias.note = f"Created by directory {directory.name}" Session.flush() for i in range(1, len(mailboxes)): AliasMailbox.create( alias_id=alias.id, mailbox_id=mailboxes[i].id, ) Session.commit() return alias except AliasInTrashError: LOG.w( "Alias %s was deleted before, cannot auto-create using directory %s, user %s", address, directory_name, user, ) return None except IntegrityError: LOG.w("Alias %s already exists", address) Session.rollback() alias = Alias.get_by(email=address) return alias
def try_auto_create_via_domain(address: str) -> Optional[Alias]: """Try to create an alias with catch-all or auto-create rules on custom domain""" # try to create alias on-the-fly with custom-domain catch-all feature # check if alias is custom-domain alias and if the custom-domain has catch-all enabled alias_domain = get_email_domain_part(address) custom_domain: CustomDomain = CustomDomain.get_by(domain=alias_domain) if not custom_domain: return None if not custom_domain.catch_all and len( custom_domain.auto_create_rules) == 0: return None elif not custom_domain.catch_all and len( custom_domain.auto_create_rules) > 0: local = get_email_local_part(address) for rule in custom_domain.auto_create_rules: if regex_match(rule.regex, local): LOG.d( "%s passes %s on %s", address, rule.regex, custom_domain, ) alias_note = f"Created by rule {rule.order} with regex {rule.regex}" mailboxes = rule.mailboxes break else: # no rule passes LOG.d("no rule passed to create %s", local) return else: # catch-all is enabled mailboxes = custom_domain.mailboxes alias_note = "Created by catch-all option" domain_user: User = custom_domain.user if not domain_user.can_create_new_alias(): send_cannot_create_domain_alias(domain_user, address, alias_domain) return None # a rule can have 0 mailboxes. Happened when a mailbox is deleted if not mailboxes: LOG.d("use %s default mailbox for %s %s", domain_user, address, custom_domain) mailboxes = [domain_user.default_mailbox] try: LOG.d("create alias %s for domain %s", address, custom_domain) alias = Alias.create( email=address, user_id=custom_domain.user_id, custom_domain_id=custom_domain.id, automatic_creation=True, mailbox_id=mailboxes[0].id, ) if not custom_domain.user.disable_automatic_alias_note: alias.note = alias_note Session.flush() for i in range(1, len(mailboxes)): AliasMailbox.create( alias_id=alias.id, mailbox_id=mailboxes[i].id, ) Session.commit() return alias except AliasInTrashError: LOG.w( "Alias %s was deleted before, cannot auto-create using domain catch-all %s, user %s", address, custom_domain, domain_user, ) return None except IntegrityError: LOG.w("Alias %s already exists", address) Session.rollback() alias = Alias.get_by(email=address) return alias except DataError: LOG.w("Cannot create alias %s", address) Session.rollback() return None