Exemple #1
0
def change_user_email(token: str) -> None:
    try:
        jwt_payload = decode_jwt_token(token)
    except (
        ExpiredSignatureError,
        InvalidSignatureError,
        DecodeError,
        InvalidTokenError,
    ) as error:
        raise InvalidTokenError() from error

    if not {"exp", "new_email", "current_email"} <= set(jwt_payload):
        raise InvalidTokenError()

    new_email = sanitize_email(jwt_payload["new_email"])
    if find_user_by_email(new_email):
        return

    current_user = find_user_by_email(jwt_payload["current_email"])
    if not current_user:
        return

    current_user.email = new_email
    sessions = UserSession.query.filter_by(userId=current_user.id)
    repository.delete(*sessions)
    repository.save(current_user)

    logger.info("User has changed their email", extra={"user": current_user.id})

    return
Exemple #2
0
def create_or_update_users(rows: Iterable[dict]) -> list[User]:
    # The purpose of this function is to recreate test users on
    # staging after the staging database is reset. It's not meant to
    # be used anywhere else, and certainly not on production.
    if settings.IS_PROD:
        raise ValueError(
            "This function is not supposed to be run on production")

    users = []
    for row in rows:
        user = find_user_by_email(row["Mail"])
        birthdate = datetime.strptime(row["Date de naissance"], "%Y-%m-%d")
        if user:
            user.dateOfBirth = birthdate
            user.setPassword(settings.STAGING_TEST_USER_PASSWORD)
        else:
            user = users_api.create_account(
                email=sanitize_email(row["Mail"]),
                password=settings.STAGING_TEST_USER_PASSWORD,
                birthdate=birthdate,
                is_email_validated=True,
                send_activation_mail=False,
                remote_updates=False,
            )
            deposit = payments_api.create_deposit(user, "import_users (csv)")
            repository.save(deposit)

        user.add_beneficiary_role()
        user.lastName = row["Nom"]
        user.firstName = row["Prénom"]
        user.publicName = f"{user.firstName} {user.lastName}"
        user.phoneNumber = row["Téléphone"]
        user.departementCode = row["Département"]
        user.postalCode = row["Code postal"]
        repository.save(user)

        users.append(user)
        logger.info("Created or updated user=%s from CSV import", user.id)

    admin = find_user_by_email("*****@*****.**")
    if not admin:
        admin = users_api.create_account(
            email="*****@*****.**",
            password=settings.STAGING_TEST_USER_PASSWORD,
            birthdate=datetime(1946, 12, 24),
            is_email_validated=True,
            send_activation_mail=False,
            remote_updates=False,
        )
    admin.setPassword(settings.STAGING_TEST_USER_PASSWORD)
    admin.remove_beneficiary_role()
    admin.add_admin_role()
    admin.firstName = "Jeanne"
    admin.lastName = "Admin"
    admin.publicName = f"{user.firstName} {user.lastName}"
    repository.save(admin)
    logger.info("Created or updated admin user=%s", admin.id)
    return users
def post_for_password_token(body: ResetPasswordBodyModel) -> None:
    check_webapp_recaptcha_token(
        body.token,
        original_action="resetPassword",
        minimal_score=settings.RECAPTCHA_RESET_PASSWORD_MINIMAL_SCORE,
    )
    user = find_user_by_email(body.email)

    if not user or not user.isActive:
        # Here we also return a 204 to prevent attacker from discovering which email exists in db
        return

    generate_reset_token(user)
    repository.save(user)

    is_not_pro_user = user.isBeneficiary

    if is_not_pro_user:
        try:
            send_reset_password_email_to_user(user)
        except MailServiceException as mail_service_exception:
            app.logger.exception(
                "[send_reset_password_email_to_user] "
                "Mail service failure", mail_service_exception)
    else:
        try:
            send_reset_password_email_to_pro(user)
        except MailServiceException as mail_service_exception:
            app.logger.exception(
                "[send_reset_password_email_to_pro] "
                "Mail service failure", mail_service_exception)
Exemple #4
0
def create_account(
    email: str,
    password: str,
    birthdate: date,
    has_allowed_recommendations: bool = False,
    is_email_validated: bool = False,
    send_activation_mail: bool = True,
) -> User:
    if find_user_by_email(email):
        raise exceptions.UserAlreadyExistsException()

    user = User(
        email=format_email(email),
        dateOfBirth=datetime.combine(birthdate, datetime.min.time()),
        isEmailValidated=is_email_validated,
        departementCode="007",
        publicName=VOID_PUBLIC_NAME,  # Required because model validation requires 3+ chars
        hasSeenTutorials=False,
        firstName=VOID_FIRST_NAME,
        hasAllowedRecommendations=has_allowed_recommendations,
    )

    age = user.calculate_age()
    if not age or age < constants.ACCOUNT_CREATION_MINIMUM_AGE:
        raise exceptions.UnderAgeUserException()

    user.setPassword(password)
    repository.save(user)

    if not is_email_validated and send_activation_mail:
        request_email_confirmation(user)
    return user
def unsubscribe_user():
    source_ip = ipaddress.IPv4Address(
        request.headers.get("X-Forwarded-For", "0.0.0.0"))
    if source_ip not in SENDINBLUE_IP_RANGE and settings.IS_DEV is False:
        raise ApiErrors(
            {"IP": "Source IP address is not whitelisted"},
            status_code=401,
        )

    user_email = request.json.get("email")
    if not user_email:
        raise ApiErrors(
            {"email": "Email missing in request payload"},
            status_code=400,
        )

    user_to_unsubscribe = find_user_by_email(user_email)
    if user_to_unsubscribe is None:
        raise ApiErrors({"User": "******" % user_email},
                        status_code=400)

    user_to_unsubscribe.notificationSubscriptions = ({
        **user_to_unsubscribe.notificationSubscriptions, "marketing_email":
        False
    } if user_to_unsubscribe.notificationSubscriptions is not None else {
        "marketing_email": False
    })
    repository.save(user_to_unsubscribe)
def post_for_password_token(body: ResetPasswordBodyModel) -> None:
    try:
        check_webapp_recaptcha_token(
            body.token,
            original_action="resetPassword",
            minimal_score=settings.RECAPTCHA_RESET_PASSWORD_MINIMAL_SCORE,
        )
    except ReCaptchaException:
        raise ApiErrors({"token": "The given token is invalid"})
    user = find_user_by_email(body.email)

    if not user or not user.isActive:
        # Here we also return a 204 to prevent attacker from discovering which email exists in db
        return

    if user.is_beneficiary:
        send_email = user_emails.send_reset_password_email_to_user
    else:
        send_email = send_reset_password_email_to_pro

    try:
        send_email(user)
    except MailServiceException as mail_service_exception:
        logger.exception("Could not send reset password email",
                         extra={
                             "user": user.id,
                             "exc": str(mail_service_exception)
                         })
def refresh() -> authentication.RefreshResponse:
    email = get_jwt_identity()
    user = find_user_by_email(email)
    if not user:
        raise ApiErrors({"email": "unknown"}, status_code=401)
    users_api.update_last_connection_date(user)
    return authentication.RefreshResponse(access_token=users_api.create_user_access_token(user))
Exemple #8
0
    def execute(self, application_id: int) -> None:
        beneficiary_pre_subscription = get_application_by_id(application_id)

        user = find_user_by_email(beneficiary_pre_subscription.email)

        try:
            validate(beneficiary_pre_subscription, preexisting_account=user)

        except CantRegisterBeneficiary as cant_register_beneficiary_exception:
            self.beneficiary_repository.reject(
                beneficiary_pre_subscription,
                detail=str(cant_register_beneficiary_exception))
            send_rejection_email_to_beneficiary_pre_subscription(
                beneficiary_pre_subscription=beneficiary_pre_subscription,
                beneficiary_is_eligible=isinstance(
                    cant_register_beneficiary_exception,
                    BeneficiaryIsADuplicate),
                send_email=send_raw_email,
            )

        else:
            if not user:
                beneficiary = self.beneficiary_repository.save(
                    beneficiary_pre_subscription)
            else:
                beneficiary = users_api.activate_beneficiary(
                    user, beneficiary_pre_subscription.deposit_source)
                users_api.attach_beneficiary_import_details(
                    user, beneficiary_pre_subscription)
            send_activation_email(user=beneficiary, send_email=send_raw_email)
    def execute(self, application_id: int) -> None:
        beneficiary_pre_subscription = get_application_by_id(application_id)

        user = find_user_by_email(beneficiary_pre_subscription.email)

        try:
            validate(beneficiary_pre_subscription, preexisting_account=user)

        except CantRegisterBeneficiary as cant_register_beneficiary_exception:
            self.beneficiary_repository.reject(
                beneficiary_pre_subscription,
                detail=str(cant_register_beneficiary_exception))
            send_rejection_email_to_beneficiary_pre_subscription(
                beneficiary_pre_subscription=beneficiary_pre_subscription,
                beneficiary_is_eligible=isinstance(
                    cant_register_beneficiary_exception,
                    BeneficiaryIsADuplicate),
            )

        else:
            beneficiary = self.beneficiary_repository.save(
                beneficiary_pre_subscription, user=user)
            if user is None:
                send_activation_email(user=beneficiary)
            else:
                send_accepted_as_beneficiary_email(user=beneficiary)
Exemple #10
0
def import_new_offerer_from_csv(row: dict) -> None:
    # We can't process a row without a postal code
    if not row["Postal Code"] and not row["code_postal"]:
        logger.warning("Unable to import this line %s - %s", row[""], row["Company ID"])
        return

    existing_pro = find_user_by_email(row["Email"])
    if existing_pro:
        pro = existing_pro
    else:
        pro_model = create_user_model_from_csv(row)
        pro = create_pro_user(pro_model)
        pro.validationToken = None
        create_reset_password_token(pro, token_life_time=timedelta(days=90))

    existing_offerer = find_offerer_by_siren(row["SIREN"])
    if existing_offerer:
        offerer = existing_offerer
    else:
        offerer = create_offerer_from_csv(row)
        create_digital_venue(offerer)

    offerer.grant_access(pro)

    repository.save(pro)

    if row["SIRET"]:
        venue = create_venue_from_csv(row, offerer)
        try:
            repository.save(venue)
        except ApiErrors:
            logger.warning("Unable to save this venue %s - %s", row[""], row["Company ID"])

    else:
        logger.warning("Unable to import this venue %s - %s", row[""], row["Company ID"])
Exemple #11
0
def create_account(
    email: str,
    password: str,
    birthdate: date,
    has_allowed_recommendations: bool = False,
    is_email_validated: bool = False,
    send_activation_mail: bool = True,
) -> User:
    if find_user_by_email(email):
        raise exceptions.UserAlreadyExistsException()

    user = User(
        email=format_email(email),
        dateOfBirth=birthdate,
        isEmailValidated=is_email_validated,
        departementCode="007",
        publicName="   ",  # Required because model validation requires 3+ chars
        hasSeenTutorials=False,
        firstName="",
        hasAllowedRecommendations=has_allowed_recommendations,
    )
    user.setPassword(password)
    repository.save(user)

    if not is_email_validated and send_activation_mail:
        request_email_confirmation(user)
    return user
    def retrieve_authenticated_user(*args, **kwargs):  # type: ignore
        email = get_jwt_identity()
        user = find_user_by_email(email)
        if user is None or not user.isActive:
            logger.error("Authenticated user with email %s not found or inactive", email)
            raise ForbiddenError({"email": ["Utilisateur introuvable"]})

        return route_function(user, *args, **kwargs)
Exemple #13
0
def request_password_reset(body: RequestPasswordResetRequest) -> None:
    user = find_user_by_email(body.email)
    try:
        users_api.request_password_reset(user)
    except users_exceptions.EmailNotSent:
        raise ApiErrors(
            {"email": ["L'email n'a pas pu être envoyé"]},
            status_code=400,
        )
Exemple #14
0
def send_user_emails_for_email_change(user: User, new_email: str) -> None:
    user_with_new_email = find_user_by_email(new_email)
    if user_with_new_email:
        return

    send_information_email_change_email(user)
    link_for_email_change = _build_link_for_email_change(user.email, new_email)
    send_confirmation_email_change_email(user, new_email, link_for_email_change)

    return
def post_change_password():
    json = request.get_json()
    validate_change_password_request(json)
    user = find_user_by_email(current_user.email)
    new_password = json["newPassword"]
    new_confirmation_password = json["newConfirmationPassword"]
    old_password = json["oldPassword"]
    check_password_validity(new_password, new_confirmation_password,
                            old_password, user)
    user.setPassword(new_password)
    repository.save(user)
    return "", 204
Exemple #16
0
def get_user_profile() -> serializers.UserProfileResponse:
    identifier = get_jwt_identity()
    user = find_user_by_email(identifier)

    if user is None:
        app.logger.error("Authenticated user with email %s not found", identifier)
        raise ApiErrors({"email": ["Utilisateur introuvable"]})

    return serializers.UserProfileResponse(
        first_name=user.firstName if user.firstName != VOID_FIRST_NAME else None,
        email=user.email,
        is_beneficiary=user.isBeneficiary,
    )
Exemple #17
0
def request_password_reset(body: RequestPasswordResetRequest) -> None:
    if feature_queries.is_active(FeatureToggle.ENABLE_NATIVE_APP_RECAPTCHA):
        try:
            api_recaptcha.check_native_app_recaptcha_token(body.token)
        except api_recaptcha.ReCaptchaException:
            raise ApiErrors({"token": "The given token is not invalid"})
    user = find_user_by_email(body.email)
    try:
        users_api.request_password_reset(user)
    except users_exceptions.EmailNotSent:
        raise ApiErrors(
            {"email": ["L'email n'a pas pu être envoyé"]},
            status_code=400,
        )
Exemple #18
0
def verify_identity_document_informations(image_storage_path: str) -> None:
    email, image = _get_identity_document_informations(image_storage_path)
    valid, code = ask_for_identity_document_verification(email, image)
    if not valid:
        old_user_emails.send_document_verification_error_email(email, code)
        fraud_api.handle_document_validation_error(email, code)
        user = find_user_by_email(email)
        if user:
            message_function = {
                "invalid-age": subscription_messages.on_idcheck_invalid_age,
                "invalid-document": subscription_messages.on_idcheck_invalid_document,
                "invalid-document-date": subscription_messages.on_idcheck_invalid_document_date,
                "unread-document": subscription_messages.on_id_check_unread_document,
                "unread-mrz-document": subscription_messages.on_idcheck_unread_mrz,
            }.get(code, lambda x: None)
            message_function(user)
    delete_object(image_storage_path)
Exemple #19
0
def create_account(body: serializers.AccountRequest) -> None:
    if settings.NATIVE_ACCOUNT_CREATION_REQUIRES_RECAPTCHA:
        try:
            check_recaptcha_token_is_valid(body.token, "submit", settings.RECAPTCHA_RESET_PASSWORD_MINIMAL_SCORE)
        except ReCaptchaException:
            raise ApiErrors({"token": "The given token is not invalid"})
    try:
        api.create_account(
            email=body.email,
            password=body.password,
            birthdate=body.birthdate,
            has_allowed_recommendations=body.has_allowed_recommendations,
            is_email_validated=False,
        )
    except UserAlreadyExistsException:
        user = find_user_by_email(body.email)
        api.request_password_reset(user)
Exemple #20
0
def resend_email_validation(
        body: serializers.ResendEmailValidationRequest) -> None:
    user = find_user_by_email(body.email)
    if not user or not user.isActive:
        return
    try:
        if user.isEmailValidated:
            api.request_password_reset(user)
        else:
            api.request_email_confirmation(user)
    except exceptions.EmailNotSent:
        raise ApiErrors(
            {
                "code": "EMAIL_NOT_SENT",
                "general": ["L'email n'a pas pu être envoyé"]
            },
            status_code=400,
        )
Exemple #21
0
def create_industrial_offer_validation_config() -> None:
    logger.info("create_industrial_offer_validation_config")
    super_admin = find_user_by_email("*****@*****.**")
    previous_config_yaml = """
    minimum_score: 0.6
    rules:
        - name: "Check offer name"
          factor: 0
          conditions:
              - model: "Offer"
                attribute: "name"
                condition:
                    operator: "not in"
                    comparated:
                        - "REJECTED"
                        - "PENDING"
                        - "DRAFT"
        - name: "Check max price"
          factor: 0.7
          conditions:
              - model: "Offer"
                attribute: "max_price"
                condition:
                    operator: ">"
                    comparated: 100
    """
    config_yaml = """
    minimum_score: 0.6
    rules:
        - name: "Check offer name"
          factor: 0
          conditions:
              - model: "Offer"
                attribute: "name"
                condition:
                    operator: "contains"
                    comparated:
                        - "REJECTED"
                        - "PENDING"
    """
    import_offer_validation_config(previous_config_yaml, super_admin)
    import_offer_validation_config(config_yaml, super_admin)

    logger.info("created 2 offer validation config")
    def retrieve_authenticated_user(*args, **kwargs):  # type: ignore
        email = get_jwt_identity()
        user = find_user_by_email(email)
        if user is None or not user.isActive:
            logger.info(
                "Authenticated user with email %s not found or inactive",
                email)
            raise ForbiddenError({"email": ["Utilisateur introuvable"]})

        # push the user to the current context - similar to flask-login
        ctx = _request_ctx_stack.top
        ctx.user = user

        # the user is set in sentry in before_request, way before we do the
        # token auth so it needs to be also set here.
        sentry_sdk.set_user({"id": user.id})
        sentry_sdk.set_tag("device.id", request.headers.get("device-id", None))

        return route_function(user, *args, **kwargs)
Exemple #23
0
def create_account(body: serializers.AccountRequest) -> None:
    if feature_queries.is_active(FeatureToggle.ENABLE_NATIVE_APP_RECAPTCHA):
        try:
            api_recaptcha.check_native_app_recaptcha_token(body.token)
        except api_recaptcha.ReCaptchaException:
            raise ApiErrors({"token": "The given token is not invalid"})
    try:
        api.create_account(
            email=body.email,
            password=body.password,
            birthdate=body.birthdate,
            has_allowed_recommendations=body.has_allowed_recommendations,
            is_email_validated=False,
        )
    except exceptions.UserAlreadyExistsException:
        user = find_user_by_email(body.email)
        api.request_password_reset(user)
    except exceptions.UnderAgeUserException:
        raise ApiErrors({"dateOfBirth": "The birthdate is invalid"})
Exemple #24
0
def create_account(
    email: str,
    password: str,
    birthdate: date,
    marketing_email_subscription: bool = False,
    is_email_validated: bool = False,
    send_activation_mail: bool = True,
    remote_updates: bool = True,
    postal_code: str = None,
    phone_number: str = None,
    apps_flyer_user_id: str = None,
    apps_flyer_platform: str = None,
) -> User:
    email = sanitize_email(email)
    if find_user_by_email(email):
        raise exceptions.UserAlreadyExistsException()

    departement_code = PostalCode(postal_code).get_departement_code() if postal_code else None

    user = User(
        email=email,
        dateOfBirth=datetime.combine(birthdate, datetime.min.time()),
        isEmailValidated=is_email_validated,
        publicName=VOID_PUBLIC_NAME,  # Required because model validation requires 3+ chars
        hasSeenTutorials=False,
        notificationSubscriptions=asdict(NotificationSubscriptions(marketing_email=marketing_email_subscription)),
        postalCode=postal_code,
        departementCode=departement_code,
        phoneNumber=phone_number,
        lastConnectionDate=datetime.now(),
    )

    if not user.age or user.age < constants.ACCOUNT_CREATION_MINIMUM_AGE:
        raise exceptions.UnderAgeUserException()

    return initialize_account(
        user, password, apps_flyer_user_id, apps_flyer_platform, send_activation_mail, remote_updates
    )
Exemple #25
0
def create_account(body: serializers.AccountRequest) -> None:
    if FeatureToggle.ENABLE_NATIVE_APP_RECAPTCHA.is_active():
        try:
            api_recaptcha.check_native_app_recaptcha_token(body.token)
        except api_recaptcha.ReCaptchaException:
            raise ApiErrors({"token": "The given token is not invalid"})

    try:
        api.create_account(
            email=body.email,
            password=body.password,
            birthdate=body.birthdate,
            marketing_email_subscription=body.marketing_email_subscription,
            is_email_validated=False,
            postal_code=body.postal_code,
            apps_flyer_user_id=body.apps_flyer_user_id,
            apps_flyer_platform=body.apps_flyer_platform,
        )
    except exceptions.UserAlreadyExistsException:
        user = find_user_by_email(body.email)
        if not user.isEmailValidated:
            try:
                api.initialize_account(
                    user,
                    body.password,
                    apps_flyer_user_id=body.apps_flyer_user_id,
                    apps_flyer_platform=body.apps_flyer_platform,
                )
            except exceptions.EmailNotSent:
                raise ApiErrors({"email": ["L'email n'a pas pu être envoyé"]})
        else:
            try:
                api.request_password_reset(user)
            except exceptions.EmailNotSent:
                raise ApiErrors({"email": ["L'email n'a pas pu être envoyé"]})
    except exceptions.UnderAgeUserException:
        raise ApiErrors({"dateOfBirth": "The birthdate is invalid"})
def process_parsing_error(exception: DMSParsingError, procedure_id: int, application_id: int) -> None:
    logger.info(
        "[BATCH][REMOTE IMPORT BENEFICIARIES] Invalid values (%r) detected in Application %s in procedure %s",
        exception.errors,
        application_id,
        procedure_id,
    )
    user = find_user_by_email(exception.user_email)
    user_emails.send_dms_wrong_values_emails(
        exception.user_email, exception.errors.get("postal_code"), exception.errors.get("id_piece_number")
    )
    if user:
        subscription_messages.on_dms_application_parsing_errors(user, list(exception.errors.keys()))
    errors = ",".join([f"'{key}' ({value})" for key, value in sorted(exception.errors.items())])
    error_detail = f"Erreur dans les données soumises dans le dossier DMS : {errors}"
    # keep a compatibility with BeneficiaryImport table
    save_beneficiary_import_with_status(
        ImportStatus.ERROR,
        application_id,
        source=BeneficiaryImportSources.demarches_simplifiees,
        source_id=procedure_id,
        detail=error_detail,
        user=user,
    )
Exemple #27
0
def _check_email_is_not_taken(beneficiary_pre_subscription: BeneficiaryPreSubscription) -> None:
    email = beneficiary_pre_subscription.email

    if find_user_by_email(email):
        raise BeneficiaryIsADuplicate(f"Email {email} is already taken.")
Exemple #28
0
def get_profile():
    user = find_user_by_email(current_user.email)
    return jsonify(as_dict(user, includes=USER_INCLUDES)), 200
Exemple #29
0
def refresh() -> authentication.RefreshResponse:
    email = get_jwt_identity()
    user = find_user_by_email(email)
    return authentication.RefreshResponse(
        access_token=create_user_access_token(user))
    def execute(
        self,
        application_id: int,
        run_fraud_detection: bool = True,
        ignore_id_piece_number_field: bool = False,
        fraud_detection_ko: bool = False,
    ) -> None:
        try:
            jouve_content = jouve_backend.get_application_content(
                application_id,
                ignore_id_piece_number_field=ignore_id_piece_number_field)
            beneficiary_pre_subscription = jouve_backend.get_subscription_from_content(
                jouve_content)
        except jouve_backend.ApiJouveException as api_jouve_exception:
            logger.error(
                api_jouve_exception.message,
                extra={
                    "route": api_jouve_exception.route,
                    "statusCode": api_jouve_exception.status_code,
                    "applicationId": application_id,
                },
            )
            return
        except jouve_backend.JouveContentValidationError as exc:
            logger.error(
                "Validation error when parsing Jouve content: %s",
                exc.message,
                extra={
                    "application_id": application_id,
                    "validation_errors": exc.errors
                },
            )
            return

        preexisting_account = find_user_by_email(
            beneficiary_pre_subscription.email)
        if not preexisting_account:
            save_beneficiary_import_with_status(
                ImportStatus.ERROR,
                application_id,
                source=BeneficiaryImportSources.demarches_simplifiees,
                source_id=jouve_backend.DEFAULT_JOUVE_SOURCE_ID,
                detail=
                f"Aucun utilisateur trouvé pour l'email {beneficiary_pre_subscription.email}",
            )
            return

        try:
            on_jouve_result(preexisting_account, jouve_content)
        except Exception as exc:  # pylint: disable=broad-except
            logger.exception("Error on jouve result: %s", exc)

        try:
            validate(
                beneficiary_pre_subscription,
                preexisting_account=preexisting_account,
                ignore_id_piece_number_field=ignore_id_piece_number_field,
            )
            if fraud_detection_ko:
                raise FraudDetected(
                    "Forced by 'fraud_detection_ko' script argument")
            if run_fraud_detection:
                validate_fraud(beneficiary_pre_subscription)

        except SuspiciousFraudDetected:
            send_fraud_suspicion_email(beneficiary_pre_subscription)
            subscription_messages.create_message_jouve_manual_review(
                preexisting_account, application_id=application_id)
        except FraudDetected as cant_register_beneficiary_exception:
            # detail column cannot contain more than 255 characters
            detail = f"Fraud controls triggered: {cant_register_beneficiary_exception}"[:
                                                                                        255]
            self.beneficiary_repository.reject(
                beneficiary_pre_subscription,
                detail=detail,
                user=preexisting_account,
            )
        except BeneficiaryIsADuplicate as exception:
            exception_reason = str(exception)

            logger.info(
                "User is a duplicate : cannot register user from application",
                extra={
                    "applicationId": application_id,
                    "reason": exception_reason,
                },
            )
            subscription_messages.on_duplicate_user(preexisting_account)
            self.beneficiary_repository.reject(beneficiary_pre_subscription,
                                               detail=exception_reason,
                                               user=preexisting_account)

            old_user_emails.send_rejection_email_to_beneficiary_pre_subscription(
                beneficiary_pre_subscription=beneficiary_pre_subscription,
                beneficiary_is_eligible=True)
        except SubscriptionJourneyOnHold as exc:
            logger.warning("User subscription is on hold",
                           extra={
                               "applicationId": application_id,
                               "reason": str(exc)
                           })
        except CantRegisterBeneficiary as cant_register_beneficiary_exception:
            exception_reason = str(cant_register_beneficiary_exception)
            logger.warning(
                "Couldn't register user from application",
                extra={
                    "applicationId": application_id,
                    "reason": exception_reason,
                },
            )
            self.beneficiary_repository.reject(beneficiary_pre_subscription,
                                               detail=exception_reason,
                                               user=preexisting_account)
            old_user_emails.send_rejection_email_to_beneficiary_pre_subscription(
                beneficiary_pre_subscription=beneficiary_pre_subscription,
                beneficiary_is_eligible=False)
        else:
            user = self.beneficiary_repository.save(
                beneficiary_pre_subscription, user=preexisting_account)
            logger.info("User registered from application",
                        extra={
                            "applicationId": application_id,
                            "userId": user.id
                        })