Example #1
0
    def test_application_with_known_email_are_saved_as_rejected(
            self, process_beneficiary_application, app):
        # given
        get_all_application_ids = Mock(return_value=[123])
        find_applications_ids_to_retry = Mock(return_value=[])

        get_details = Mock(
            return_value=make_old_application_detail(123, "closed"))
        user = User()
        user.email = "*****@*****.**"
        has_already_been_imported = Mock(return_value=False)
        has_already_been_created = Mock(return_value=True)

        # when
        old_remote_import.run(
            ONE_WEEK_AGO,
            get_all_applications_ids=get_all_application_ids,
            get_applications_ids_to_retry=find_applications_ids_to_retry,
            get_details=get_details,
            already_imported=has_already_been_imported,
            already_existing_user=has_already_been_created,
        )

        # then
        beneficiary_import = BeneficiaryImport.query.first()
        assert beneficiary_import.currentStatus == ImportStatus.REJECTED
        assert beneficiary_import.applicationId == 123
        assert beneficiary_import.detail == "Compte existant avec cet email"
        process_beneficiary_application.assert_not_called()
Example #2
0
def activate_beneficiary(
    user: users_models.User, deposit_source: str = None, has_activated_account: Optional[bool] = True
) -> users_models.User:
    if not deposit_source:
        beneficiary_import = subscription_repository.get_beneficiary_import_for_beneficiary(user)
        if not beneficiary_import:
            raise exceptions.BeneficiaryImportMissingException()

        eligibility = beneficiary_import.eligibilityType
        deposit_source = beneficiary_import.get_detailed_source()
    else:
        eligibility = users_models.EligibilityType.AGE18

    if eligibility == users_models.EligibilityType.UNDERAGE:
        user.add_underage_beneficiary_role()
    elif eligibility == users_models.EligibilityType.AGE18:
        user.add_beneficiary_role()
    else:
        raise users_exception.InvalidEligibilityTypeException()

    if "apps_flyer" in user.externalIds:
        apps_flyer_job.log_user_becomes_beneficiary_event_job.delay(user.id)

    deposit = payments_api.create_deposit(user, deposit_source=deposit_source, eligibility=eligibility)

    db.session.add_all((user, deposit))
    db.session.commit()
    logger.info("Activated beneficiary and created deposit", extra={"user": user.id, "source": deposit_source})

    db.session.refresh(user)

    update_external_user(user)
    _send_beneficiary_activation_email(user, has_activated_account)

    return user
Example #3
0
    def on_model_change(self, form: Form, model: User, is_created: bool) -> None:
        if is_created:
            model.password = random_password()

        model.publicName = f"{model.firstName} {model.lastName}"
        model.isBeneficiary = False
        model.isAdmin = False
Example #4
0
    def test_application_with_known_application_id_are_not_processed(
            self, process_beneficiary_application):
        # given
        get_all_application_ids = Mock(return_value=[123, 456])
        find_applications_ids_to_retry = Mock(return_value=[])

        get_details = Mock(
            return_value=make_old_application_detail(123, "closed"))
        user = User()
        user.email = "*****@*****.**"
        has_already_been_imported = Mock(return_value=True)
        has_already_been_created = Mock(return_value=False)

        # when
        old_remote_import.run(
            ONE_WEEK_AGO,
            get_all_applications_ids=get_all_application_ids,
            get_applications_ids_to_retry=find_applications_ids_to_retry,
            get_details=get_details,
            already_imported=has_already_been_imported,
            already_existing_user=has_already_been_created,
        )

        # then
        process_beneficiary_application.assert_not_called()
Example #5
0
    def test_should_raise_multiple_errors_at_once(self):
        # given
        user = User()
        user.setPassword("weakpassword")
        new_password = "******"
        new_confirmation_password = "******"
        old_password = "******"

        # when
        with pytest.raises(ApiErrors) as api_errors:
            check_password_validity(new_password, new_confirmation_password,
                                    old_password, user)

        # then
        assert api_errors.value.errors["newPassword"] == [
            "Ton mot de passe doit contenir au moins :\n"
            "- 12 caractères\n"
            "- Un chiffre\n"
            "- Une majuscule et une minuscule\n"
            "- Un caractère spécial",
            "Ton nouveau mot de passe est identique à l’ancien.",
        ]

        assert api_errors.value.errors["newConfirmationPassword"] == [
            "Les deux mots de passe ne sont pas identiques."
        ]
Example #6
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
Example #7
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
Example #8
0
def initialize_account(
    user: User,
    password: str,
    apps_flyer_user_id: str = None,
    apps_flyer_platform: str = None,
    send_activation_mail: bool = True,
    remote_updates: bool = True,
) -> User:

    user.setPassword(password)
    if apps_flyer_user_id and apps_flyer_platform:
        if user.externalIds is None:
            user.externalIds = {}
        user.externalIds["apps_flyer"] = {"user": apps_flyer_user_id, "platform": apps_flyer_platform.upper()}

    repository.save(user)
    logger.info("Created user account", extra={"user": user.id})
    delete_all_users_tokens(user)

    if remote_updates:
        update_external_user(user)

    if not user.isEmailValidated and send_activation_mail:
        request_email_confirmation(user)

    return user
Example #9
0
def fulfill_user_data(user: User, deposit_source: str) -> User:
    user.password = random_password()
    generate_reset_token(user, validity_duration_hours=THIRTY_DAYS_IN_HOURS)

    deposit = payment_api.create_deposit(user, deposit_source)
    user.deposits = [deposit]

    return user
Example #10
0
def _set_offerer_departement_code(new_user: User, offerer: Offerer) -> User:
    if settings.IS_INTEGRATION:
        new_user.departementCode = "00"
    elif offerer.postalCode is not None:
        new_user.departementCode = PostalCode(offerer.postalCode).get_departement_code()
    else:
        new_user.departementCode = "XX"  # We don't want to trigger an error on this:
        # we want the error on user
    return new_user
    def test_a_partner_should_never_be_a_beneficiary(self, app, db_session):
        # given
        user = User()
        user.add_beneficiary_role()
        view = PartnerUserView(model=User, session=db_session)

        # when
        view.on_model_change(Form(), model=user, is_created=False)

        # then
        assert not user.has_beneficiary_role
    def test_should_generate_a_random_password_on_creation(self, app, db_session):
        # given
        user = User()
        user.password = None
        view = PartnerUserView(model=User, session=db_session)

        # when
        view.on_model_change(Form(), model=user, is_created=True)

        # then
        assert user.password is not None
Example #13
0
    def test_should_preserve_password_on_edition(self, app, db_session):
        # given
        user = User()
        user.password = "******"
        view = PartnerUserView(model=User, session=db_session)

        # when
        view.on_model_change(Form(), model=user, is_created=False)

        # then
        assert user.password == "OriginalPassword"
Example #14
0
def unsuspend_account(user: User, actor: User) -> None:
    user.isActive = True
    user.suspensionReason = ""
    repository.save(user)

    logger.info(
        "Account has been unsuspended",
        extra={
            "actor": actor.id,
            "user": user.id,
        },
    )
Example #15
0
def update_cultural_survey(user: User,
                           body: serializers.CulturalSurveyRequest) -> None:
    with transaction():
        if not body.needs_to_fill_cultural_survey:
            user.needsToFillCulturalSurvey = False
        if body.cultural_survey_id:
            logger.info("User %s updated cultural survey",
                        user.id,
                        extra={"actor": user.id})
            user.culturalSurveyId = body.cultural_survey_id
            user.culturalSurveyFilledDate = datetime.now()
    return
Example #16
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)
Example #17
0
    def test_should_create_the_public_name(self, app, db_session):
        # Given
        user = User()
        user.firstName = "Ken"
        user.lastName = "Thompson"
        user.publicName = None
        view = ProUserView(model=User, session=db_session)

        # When
        view.on_model_change(Form(), model=user, is_created=False)

        # Then
        assert user.publicName == "Ken Thompson"
    def test_does_not_raise_error_when_user_is_authenticated(self):
        # Given
        user = User()
        user.is_authenticated = True
        email = "*****@*****.**"

        # When
        try:
            check_user_is_logged_in_or_email_is_provided(user, email)

        # Then
        except ApiErrors:
            assert False
Example #19
0
    def test_check_user_can_validate_v2_bookings_raise_api_error_when_user_is_authenticated_but_does_not_have_editor_rights_on_booking(
            self, app):
        # Given
        user = User()
        user.is_authenticated = True

        # When
        with pytest.raises(ApiErrors) as errors:
            check_user_can_validate_bookings_v2(user, None)

        # Then
        assert errors.value.errors["user"] == [
            "Vous n'avez pas les droits suffisants pour valider cette contremarque."
        ]
Example #20
0
    def test_check_user_can_validate_bookings_raise_api_error_when_user_is_authenticated_and_does_not_have_editor_rights_on_booking(
            self, app):
        # Given
        user = User()
        user.is_authenticated = True

        # When
        with pytest.raises(ApiErrors) as errors:
            check_user_can_validate_bookings(user, None)

        # Then
        assert errors.value.errors["global"] == [
            "Cette contremarque n'a pas été trouvée"
        ]
Example #21
0
    def on_model_change(self, form: Form, model: User,
                        is_created: bool) -> None:
        model.publicName = f"{model.firstName} {model.lastName}"

        if is_created:
            model.isBeneficiary = False
            model.password = random_password()
            generate_reset_token(model, 24 * 14)
            offerer = create_offerer(form)
            create_digital_venue(offerer)
            user_offerer = create_user_offerer(user=model, offerer=offerer)
            model.userOfferers = [user_offerer]

        super().on_model_change(form, model, is_created)
Example #22
0
    def test_check_user_can_validate_v2_bookings_raise_api_error_when_user_is_authenticated_but_does_not_have_editor_rights_on_booking(
            self, app):
        # Given
        user = User()
        user.is_authenticated = True

        # When
        with pytest.raises(ApiErrors) as errors:
            check_user_can_validate_bookings_v2(user, None)

        # Then
        assert errors.value.errors["user"] == [
            "Vous n’avez pas les droits suffisants pour valider cette contremarque car cette réservation n'a pas été faite sur une de vos offres, ou que votre rattachement à la structure est encore en cours de validation"
        ]
Example #23
0
def update_cultural_survey(user: User,
                           body: serializers.CulturalSurveyRequest) -> None:
    with transaction():
        if not body.needs_to_fill_cultural_survey:
            user.needsToFillCulturalSurvey = False
        if body.cultural_survey_id:
            if user.culturalSurveyId:
                raise ApiErrors({
                    "culturalSurveyId":
                    "L'utilisateur a déjà rempli le formulaire"
                })
            user.culturalSurveyId = body.cultural_survey_id
            user.culturalSurveyFilledDate = datetime.now()
    return
Example #24
0
def get_user_attributes(user: User) -> UserAttributes:
    from pcapi.core.users.api import get_domains_credit

    is_pro_user = user.has_pro_role or db.session.query(
        UserOfferer.query.filter_by(userId=user.id).exists()).scalar()
    user_bookings: List[Booking] = _get_user_bookings(
        user) if not is_pro_user else []
    last_favorite = (Favorite.query.filter_by(userId=user.id).order_by(
        Favorite.id.desc()).first() if not is_pro_user else None)
    domains_credit = get_domains_credit(
        user, user_bookings) if not is_pro_user else None
    booking_categories, booking_subcategories = _get_bookings_categories_and_subcategories(
        user_bookings)

    return UserAttributes(
        booking_categories=booking_categories,
        booking_count=len(user_bookings),
        booking_subcategories=booking_subcategories,
        date_created=user.dateCreated,
        date_of_birth=user.dateOfBirth,
        departement_code=user.departementCode,
        deposit_activation_date=user.deposit_activation_date,
        deposit_expiration_date=user.deposit_expiration_date,
        domains_credit=domains_credit,
        eligibility=user.eligibility,
        first_name=user.firstName,
        has_completed_id_check=user.hasCompletedIdCheck,
        user_id=user.id,
        is_beneficiary=user.has_beneficiary_role,
        is_eligible=user.is_eligible,
        is_email_validated=user.isEmailValidated,
        is_pro=is_pro_user,
        last_booking_date=user_bookings[0].dateCreated
        if user_bookings else None,
        last_favorite_creation_date=last_favorite.dateCreated
        if last_favorite else None,
        last_name=user.lastName,
        last_visit_date=user.lastConnectionDate,
        marketing_email_subscription=user.get_notification_subscriptions(
        ).marketing_email,
        marketing_push_subscription=user.get_notification_subscriptions().
        marketing_push,
        postal_code=user.postalCode,
        products_use_date={
            f"product_{TRACKED_PRODUCT_IDS[booking.stock.offer.productId]}_use":
            booking.dateUsed
            for booking in user_bookings if booking.dateUsed
            and booking.stock.offer.productId in TRACKED_PRODUCT_IDS
        },
    )
    def test_raises_an_error_when_no_email_nor_user_logged(self):
        # Given
        user = User()
        user.is_authenticated = False
        email = None

        # When
        with pytest.raises(ApiErrors) as excinfo:
            check_user_is_logged_in_or_email_is_provided(user, email)

        # Then
        assert excinfo.value.errors["email"] == [
            "Vous devez préciser l'email de l'utilisateur quand vous n'êtes pas connecté(e)"
        ]
Example #26
0
def create_pro_user(pro_user: ProUserCreationBodyModel) -> User:
    objects_to_save = []

    new_pro_user = User(from_dict=pro_user.dict(by_alias=True))
    new_pro_user.hasAllowedRecommendations = pro_user.contact_ok

    existing_offerer = Offerer.query.filter_by(siren=pro_user.siren).first()

    if existing_offerer:
        user_offerer = _generate_user_offerer_when_existing_offerer(new_pro_user, existing_offerer)
        offerer = existing_offerer
    else:
        offerer = _generate_offerer(pro_user.dict(by_alias=True))
        user_offerer = offerer.grant_access(new_pro_user)
        digital_venue = create_digital_venue(offerer)
        objects_to_save.extend([digital_venue, offerer])
    objects_to_save.append(user_offerer)
    new_pro_user.isBeneficiary = False
    new_pro_user.isAdmin = False
    new_pro_user.needsToFillCulturalSurvey = False
    new_pro_user = _set_offerer_departement_code(new_pro_user, offerer)

    new_pro_user.generate_validation_token()
    objects_to_save.append(new_pro_user)

    repository.save(*objects_to_save)

    try:
        user_emails.send_user_validation_email(new_pro_user)
    except MailServiceException:
        logger.exception("Could not send validation email when creating pro user=%s", new_pro_user.id)

    return new_pro_user
Example #27
0
def fill_user_from(csv_row: list[str], user: User) -> User:
    user.lastName = csv_row[USER_LAST_NAME_COLUMN_INDEX]
    user.firstName = csv_row[USER_FIRST_NAME_COLUMN_INDEX].split(" ")[0]
    user.publicName = "%s %s" % (user.firstName, user.lastName)
    user.email = sanitize_email(csv_row[USER_EMAIL_COLUMN_INDEX])
    user.departementCode = csv_row[USER_DEPARTMENT_CODE_COLUMN_INDEX]
    user.remove_beneficiary_role()
    user.add_pro_role()

    fulfill_account_password(user)
    return user
Example #28
0
    def test_change_password_raises_an_error_if_new_confirmation_password_is_not_given_as_key_in_json(
            self):
        # given
        user = User()
        user.setPassword("0ld__p455w0rd")
        json = {"oldPassword": "******", "newPassword": "******"}

        # when
        with pytest.raises(ApiErrors) as api_errors:
            validate_change_password_request(json)

        # then
        assert api_errors.value.errors["newConfirmationPassword"] == [
            "Confirmation du nouveau mot de passe manquante"
        ]
Example #29
0
    def test_change_password_should_add_an_error_if_old_password_does_not_match_existing_password(
            self):
        # given
        api_errors = ApiErrors()
        user = User()
        user.setPassword("0ld__p455w0rd")
        old_password = "******"

        # when
        _ensure_given_old_password_is_correct(user, old_password, api_errors)

        # then
        assert api_errors.errors["oldPassword"] == [
            "Ton ancien mot de passe est incorrect."
        ]
def change_password(user: User, body: ChangePasswordRequest) -> None:
    try:
        users_repo.check_user_and_credentials(user, body.current_password)
    except users_exceptions.InvalidIdentifier:
        raise ApiErrors({"code": "INVALID_PASSWORD", "currentPassword": ["Le mot de passe est incorrect"]})
    except users_exceptions.CredentialsException:
        raise ForbiddenError()

    try:
        check_password_strength("newPassword", body.new_password)
    except ApiErrors:
        raise ApiErrors({"code": "WEAK_PASSWORD", "newPassword": ["Le nouveau mot de passe est trop faible"]})

    user.setPassword(body.new_password)
    repository.save(user)