def delete_unwanted_existing_product(isbn: str):
    product_has_at_least_one_booking = (Product.query.filter_by(
        idAtProviders=isbn).join(Offer).join(Stock).join(Booking).count() > 0)
    product = find_active_book_product_by_isbn(isbn)

    if not product:
        return

    if product_has_at_least_one_booking:
        offers = get_offers_by_product_id(product.id)
        product.isGcuCompatible = False
        offers = update_is_active_status(offers, False)
        repository.save(*offers, product)
        raise ProductWithBookingsException

    objects_to_delete = []
    objects_to_delete.append(product)
    offers = get_offers_by_product_id(product.id)
    offer_ids = [offer.id for offer in offers]
    objects_to_delete = objects_to_delete + offers
    stocks = offers_repository.get_stocks_for_offers(offer_ids)
    objects_to_delete = objects_to_delete + stocks
    mediations = get_mediations_for_offers(offer_ids)
    objects_to_delete = objects_to_delete + mediations
    favorites = get_favorites_for_offers(offer_ids)
    objects_to_delete = objects_to_delete + favorites
    repository.delete(*objects_to_delete)
Esempio n. 2
0
    def test_when_no_deposit(self):
        # given
        user = UserFactory()
        repository.delete(*user.deposits)

        # then
        assert user.deposit_version == None
Esempio n. 3
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 = jwt_payload["new_email"]
    if User.query.filter_by(email=new_email).first():
        return

    current_email = jwt_payload["current_email"]
    current_user = User.query.filter_by(email=current_email).first()
    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)

    return
Esempio n. 4
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
Esempio n. 5
0
    def test_balance_is_0_with_no_deposits_and_no_bookings(self):
        # given
        user = factories.UserFactory()
        repository.delete(user.deposit)

        # then
        assert user.wallet_balance == 0
        assert user.real_wallet_balance == 0
Esempio n. 6
0
def delete_favorite(offer_id):
    dehumanized_offer_id = dehumanize(offer_id)

    favorite = find_favorite_for_offer_and_user(dehumanized_offer_id, current_user.id).first_or_404()

    repository.delete(favorite)

    return jsonify(as_dict(favorite)), 200
Esempio n. 7
0
def create_mediation_v2(
    user: User,
    offer: Offer,
    credit: str,
    image_as_bytes: bytes,
    crop_params: tuple = None,
) -> Mediation:
    # checks image type, min dimensions
    validation.check_image(image_as_bytes)

    existing_mediations = mediation_queries.get_mediations_for_offers(
        [offer.id])

    mediation = Mediation(
        author=user,
        offer=offer,
        credit=credit,
    )
    # `create_thumb()` requires the object to have an id, so we must save now.
    repository.save(mediation)

    try:
        # TODO(fseguin): cleanup after image upload v2 launch
        create_thumb(mediation,
                     image_as_bytes,
                     image_index=0,
                     crop_params=crop_params,
                     use_v2=True)

    except Exception as exc:
        app.logger.exception(
            "An unexpected error was encountered during the thumbnail creation: %s",
            exc)
        # I could not use savepoints and rollbacks with SQLA
        repository.delete(mediation)
        raise ThumbnailStorageError

    else:
        mediation.thumbCount = 1
        repository.save(mediation)
        # cleanup former thumbnails and mediations
        for previous_mediation in existing_mediations:
            try:
                for thumb_index in range(0, mediation.thumbCount):
                    remove_thumb(previous_mediation, image_index=thumb_index)
            except Exception as exc:  # pylint: disable=broad-except
                app.logger.exception(
                    "An unexpected error was encountered during the thumbnails deletion for %s: %s",
                    mediation,
                    exc,
                )
            else:
                repository.delete(previous_mediation)

        if feature_queries.is_active(FeatureToggle.SYNCHRONIZE_ALGOLIA):
            redis.add_offer_id(client=app.redis_client, offer_id=offer.id)

        return mediation
Esempio n. 8
0
def delete_corrupted_allocine_stocks():
    new_stock_id_at_providers_format = "%#%"
    allocine_provider = get_provider_by_local_class("AllocineStocks")
    stocks_to_delete = (Stock.query.filter_by(
        lastProviderId=allocine_provider.id
    ).filter_by(isSoftDeleted=True).filter(
        Stock.idAtProviders.notilike(new_stock_id_at_providers_format)).all())

    repository.delete(*stocks_to_delete)
def _delete_user_offerers_from_rows(csv_rows: Iterable) -> None:
    user_offerers_successful = []
    user_offerers_in_error = []

    csv_rows_iterable = iter(csv_rows)
    headers = next(csv_rows_iterable)
    for row in csv_rows_iterable:
        if _is_blank_row(row):
            continue

        row = dict(zip(headers, row))
        user_id = row[USER_ID_COLUMN_HEADER]
        offerer_id = row[OFFERER_ID_COLUMN_HEADER]

        user_offerer = find_one_or_none_by_user_id_and_offerer_id(
            int(user_id), int(offerer_id))
        if user_offerer is None:
            continue

        user_offerer_id = user_offerer.id

        logger.info(
            "[DELETE USER_OFFERERS FROM FILE] Suppression du rattachement pour le user d'id %s et l'offerer "
            "d'id %s est lancée",
            user_id,
            offerer_id,
        )

        try:
            repository.delete(user_offerer)
            logger.info(
                "[DELETE USER_OFFERERS FROM FILE] Suppression du rattachement pour le user d'id %s et l'offerer "
                "d'id %s réussie",
                user_id,
                offerer_id,
            )
            user_offerers_successful.append(user_offerer_id)
        except ApiErrors as error:
            logger.exception(
                "[DELETE USER_OFFERERS FROM FILE] %s pour le rattachement avec le user d'id %s et l'offerer d'id %s",
                error.errors,
                user_id,
                offerer_id,
            )
            user_offerers_in_error.append(user_offerer_id)

    logger.info("[DELETE USER_OFFERERS FROM FILE] %i RATTACHEMENT SUPPRIMES",
                len(user_offerers_successful))
    logger.info(
        "[DELETE USER_OFFERERS FROM FILE] LISTE DES RATTACHEMENT SUPPRIMES")
    logger.info(user_offerers_successful)

    if len(user_offerers_in_error) > 0:
        logger.error(
            "[DELETE USER_OFFERERS FROM FILE] LISTE DES RATTACHEMENTS EN ERREUR"
        )
        logger.error(user_offerers_in_error)
Esempio n. 10
0
def create_mediation(
    user: User,
    offer: Offer,
    credit: str,
    image_as_bytes: bytes,
    crop_params: tuple = None,
) -> Mediation:
    # checks image type, min dimensions
    validation.check_image(image_as_bytes)

    mediation = Mediation(
        author=user,
        offer=offer,
        credit=credit,
    )
    # `create_thumb()` requires the object to have an id, so we must save now.
    repository.save(mediation)

    try:
        create_thumb(mediation,
                     image_as_bytes,
                     image_index=0,
                     crop_params=crop_params)

    except Exception as exc:
        logger.exception(
            "An unexpected error was encountered during the thumbnail creation: %s",
            exc)
        # I could not use savepoints and rollbacks with SQLA
        repository.delete(mediation)
        raise ThumbnailStorageError

    else:
        mediation.thumbCount = 1
        repository.save(mediation)
        # cleanup former thumbnails and mediations

        previous_mediations = (Mediation.query.filter(
            Mediation.offerId == offer.id).filter(
                Mediation.id != mediation.id).all())
        for previous_mediation in previous_mediations:
            try:
                for thumb_index in range(0, previous_mediation.thumbCount):
                    remove_thumb(previous_mediation, image_index=thumb_index)
            except Exception as exc:  # pylint: disable=broad-except
                logger.exception(
                    "An unexpected error was encountered during the thumbnails deletion for %s: %s",
                    mediation,
                    exc,
                )
            else:
                repository.delete(previous_mediation)

        search.async_index_offer_ids([offer.id])

        return mediation
Esempio n. 11
0
def change_pro_users_to_beneficiary(pro_users_ids: List[int]) -> None:
    users = User.query.filter(User.id.in_(pro_users_ids)).all()
    maximum_wallet_balance = 500
    for user in users:
        user.isBeneficiary = True
        user.needsToFillCulturalSurvey = True
        deposit = create_deposit(user, amount=maximum_wallet_balance)
        repository.save(user, deposit)
        user_offerer = UserOfferer.query.filter_by(user=user).all()
        repository.delete(*user_offerer)
def change_pro_users_to_beneficiary(pro_users_ids: list[int]) -> None:
    users = User.query.filter(User.id.in_(pro_users_ids)).all()
    for user in users:
        user.add_beneficiary_role()
        user.remove_pro_role()
        user.needsToFillCulturalSurvey = True
        deposit = payments_api.create_deposit(user, "public")
        repository.save(user, deposit)
        user_offerer = UserOfferer.query.filter_by(user=user).all()
        repository.delete(*user_offerer)
Esempio n. 13
0
    def test_deposit_created_with_an_expiration_date(self, app):
        # Given
        beneficiary = UserFactory(email="*****@*****.**")
        repository.delete(*beneficiary.deposits)

        # When
        deposit = create_deposit(beneficiary, "created by test")

        # Then
        assert deposit.expirationDate == datetime(2023, 2, 5, 9, 0, 0)
Esempio n. 14
0
    def test_users_with_no_deposits_are_ignored(self):
        # given
        user1 = users_factories.BeneficiaryGrant18Factory()
        user2 = users_factories.BeneficiaryGrant18Factory()
        repository.delete(user2.deposit)

        # when
        balances = get_all_users_wallet_balances()

        # then
        assert len(balances) == 1
        assert balances[0].user_id == user1.id
Esempio n. 15
0
def suspend_account(user: User, reason: constants.SuspensionReason, actor: User) -> None:
    user.isActive = False
    user.suspensionReason = str(reason)
    # If we ever unsuspend the account, we'll have to explictly enable
    # isAdmin again. An admin now may not be an admin later.
    user.isAdmin = False
    user.setPassword(secrets.token_urlsafe(30))
    repository.save(user)

    sessions = UserSession.query.filter_by(userId=user.id)
    repository.delete(*sessions)

    logger.info("user=%s has been suspended by actor=%s for reason=%s", user.id, actor.id, reason)
Esempio n. 16
0
def delete_venue_and_offers_for_venue_id(humanized_venue_id: str):
    dehumanized_venue_id = dehumanize(humanized_venue_id)
    offers = get_offers_by_venue_id(dehumanized_venue_id)
    venue = find_by_id(dehumanized_venue_id)

    if any(offer.stocks for offer in offers):
        raise AttributeError(
            "Offres non supprimables car au moins une contient des stocks")

    for offer in offers:
        repository.delete(offer)

    if venue:
        repository.delete(venue)
Esempio n. 17
0
def test_delete_user_when_she_has_no_deposit():
    admin = users_factories.AdminFactory()
    user_without_deposit = users_factories.UserFactory(
        email="*****@*****.**")
    users_factories.FavoriteFactory(user=user_without_deposit)
    fraud_factories.BeneficiaryFraudCheckFactory(user=user_without_deposit)
    fraud_factories.BeneficiaryFraudResultFactory(user=user_without_deposit)
    fraud_factories.BeneficiaryFraudReviewFactory(user=user_without_deposit,
                                                  author=admin)

    deposit = Deposit.query.all()
    repository.delete(*deposit)
    suspend_or_delete_from_file(
        "tests/scripts/beneficiary/users_to_delete_fixture.txt",
        admin.email,
    )
    assert User.query.all() == [admin]
Esempio n. 18
0
    def when_user_is_logged_in_and_has_no_deposit(self, app):
        # Given
        user = BeneficiaryGrant18Factory(
            email="*****@*****.**",
            postalCode="93020",
        )
        repository.delete(*user.deposits)

        # When
        response = (TestClient(app.test_client()).with_session_auth(
            email="*****@*****.**").get("/beneficiaries/current"))

        # Then
        assert response.status_code == 200
        assert response.json == {
            "activity": user.activity,
            "address": user.address,
            "city": user.city,
            "civility": user.civility,
            "dateCreated": format_into_utc_date(user.dateCreated),
            "dateOfBirth": format_into_utc_date(user.dateOfBirth),
            "departementCode": user.departementCode,
            "deposit_expiration_date": None,
            "deposit_version": None,
            "domainsCredit": None,
            "email": "*****@*****.**",
            "firstName": user.firstName,
            "hasPhysicalVenues": user.hasPhysicalVenues,
            "id": humanize(user.id),
            "isActive": True,
            "isAdmin": False,
            "isBeneficiary": True,
            "isEmailValidated": True,
            "lastName": user.lastName,
            "needsToFillCulturalSurvey": True,
            "needsToSeeTutorials": True,
            "pk": user.id,
            "phoneNumber": user.phoneNumber,
            "postalCode": user.postalCode,
            "publicName": user.publicName,
            "roles": ["BENEFICIARY"],
            "suspensionReason": "",
            "wallet_balance": 0.0,
            "wallet_is_activated": False,
        }
Esempio n. 19
0
def suspend_account(user: User, reason: constants.SuspensionReason, actor: User) -> dict[str, int]:
    import pcapi.core.bookings.api as bookings_api  # avoid import loop

    user.isActive = False
    user.suspensionReason = str(reason)
    user.remove_admin_role()
    user.setPassword(secrets.token_urlsafe(30))
    repository.save(user)

    sessions = UserSession.query.filter_by(userId=user.id)
    repository.delete(*sessions)

    n_bookings = 0

    # Cancel all bookings of the related offerer if the suspended
    # account was the last active offerer's account.
    if reason == constants.SuspensionReason.FRAUD:
        for offerer in user.offerers:
            if any(u.isActive and u != user for u in offerer.users):
                continue
            bookings = bookings_repository.find_cancellable_bookings_by_offerer(offerer.id)
            for booking in bookings:
                bookings_api.cancel_booking_for_fraud(booking)
                n_bookings += 1

    # Cancel all bookings of the user (the following works even if the
    # user is not a beneficiary).
    cancel_booking_callback = {
        constants.SuspensionReason.FRAUD: bookings_api.cancel_booking_for_fraud,
        constants.SuspensionReason.UPON_USER_REQUEST: bookings_api.cancel_booking_on_user_requested_account_suspension,
    }.get(reason)
    if cancel_booking_callback:
        for booking in bookings_repository.find_cancellable_bookings_by_beneficiaries([user]):
            cancel_booking_callback(booking)
            n_bookings += 1

    logger.info(
        "Account has been suspended",
        extra={
            "actor": actor.id,
            "user": user.id,
            "reason": str(reason),
        },
    )
    return {"cancelled_bookings": n_bookings}
Esempio n. 20
0
        def when_user_is_logged_in_and_has_no_deposit(self, app):
            # Given
            user = UserFactory(
                email="*****@*****.**",
                postalCode="93020",
            )
            repository.delete(*user.deposits)

            # When
            response = TestClient(app.test_client()).with_auth(email="*****@*****.**").get("/beneficiaries/current")

            # Then
            assert response.status_code == 200
            json = response.json
            assert json["email"] == "*****@*****.**"
            assert json["expenses"] == []
            assert "password" not in json
            assert "clearTextPassword" not in json
            assert "resetPasswordToken" not in json
            assert "resetPasswordTokenValidityLimit" not in json
            assert json["wallet_is_activated"] == False
def delete_venue_from_iris_venues(venue_id: int) -> None:
    iris_venues_to_delete = IrisVenues.query.filter_by(venueId=venue_id).all()
    repository.delete(*iris_venues_to_delete)
Esempio n. 22
0
def delete_user_session(user_id: int, session_uuid: UUID):
    session = UserSession.query.filter_by(userId=user_id, uuid=session_uuid).one_or_none()

    if session:
        repository.delete(session)