예제 #1
0
def user_add():
    form = RegistrationForm()
    if request.method == 'POST' and form.validate():
        existing_user = User.get_by_email(form.email.data)
        if existing_user is None:
            user_data = {
                'username': form.username.data,
                'email': form.email.data,
                'password': form.password.data
            }
            user = User(**user_data).save()
            try:
                was_sent, error_msg = user.send_confirmation_email()
            except (ValueError, socket.error) as e:
                was_sent = False
                error_msg = str(e)
            # Enviamos el email de confirmación al usuario.
            if was_sent:
                flash(_('Se envío un correo de confirmación a: %(email)s',
                        email=user.email), 'info')
            else:
                flash(_('Ocurrió un error en el envío del correo de '
                        'confirmación  a: %(email)s %(error_msg)s',
                        email=user.email, error_msg=error_msg),
                      'error')
            return redirect(url_for('main.user_add'))
        else:
            flash(_('El correo electrónico ya esta registrado'), 'error')
    return render_template('forms/register.html', form=form)
예제 #2
0
def user_edit(user_id):
    # TODO: permitir la actualización de usuarios sin actualizar contraseña
    user = User.get_by_id(user_id)
    form = RegistrationForm(obj=user)
    if request.method == 'POST' and form.validate():
        existing_user = User.get_by_email(form.email.data)
        if existing_user is None or user.id == existing_user.id:
            update_user = User.get_by_id(user_id)
            update_user.username = form.username.data
            update_user.email = form.email.data
            update_user.password = form.password.data
            update_user.save()
            flash(_('Usuario actualizado correctamente!'), 'info')
            if user.email != update_user.email:
                user.email_confirmed = False
                user.save()
                try:
                    # TODO: enviar email de actualización
                    was_sent, error_msg = update_user.send_confirmation_email()
                except (ValueError, socket.error) as e:
                    was_sent = False
                    error_msg = str(e)
                # Enviamos el email de confirmación al usuario.
                if was_sent:
                    flash(_('Se envío un correo de confirmación a: %(email)s',
                            email=update_user.email), 'info')
                else:
                    flash(_('Ocurrió un error en el envío del correo de '
                            'confirmación  a: %(email)s %(error_msg)s',
                            email=update_user.email, error_msg=error_msg),
                          'error')
        else:
            flash(_('El correo electrónico ya esta registrado'), 'error')
    return render_template('forms/register.html', form=form)
예제 #3
0
 def test_confirmation_email_invalid_user(self):
     """Test de error cuando se trata de activar un usuario no registrado"""
     fake_email = '*****@*****.**'
     expected_error_msg = 'Usuario no encontrado'
     with current_app.app_context():
         with self.client as c:
             with mail.record_messages() as outbox:
                 notifications.send_confirmation_email(fake_email)
                 email_msg = outbox[0]
                 links_found = url_pattern.findall(email_msg.html)
                 self.assertGreaterEqual(1, len(links_found))
                 confirm_url_with_token = [
                     url for url in links_found if '/user/confirm/' in url
                 ]
                 self.assertEqual(1, len(confirm_url_with_token))
                 confirm_url_with_token = confirm_url_with_token[0]
                 # tratamos de activar con el enlace
                 response = c.get(confirm_url_with_token,
                                  follow_redirects=True)
                 self.assertStatus(response, 404)
                 self.assertEqual('text/html', response.content_type)
                 user = User.get_by_email(fake_email)
                 self.assertIsNone(user)
                 self.assertIn(expected_error_msg,
                               response.data.decode('utf-8'))
예제 #4
0
    def test_user_add_insert_one(self):
        """Test para registro de un usuario"""
        user_data = {
            'email': '*****@*****.**',
            'password': '******',
        }
        new_user_data = {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'confirm': 'F00barbaz$'
        }
        create_user(user_data['email'], user_data['password'], True)
        login_url = url_for('main.login')
        user_add_url = (url_for('main.user_add'))
        expected_msg = 'Se envío un correo de confirmación a: %s' % new_user_data[
            'email']
        with current_app.app_context():
            with self.client as c:
                # login de usuario
                c.post(login_url, data=user_data, follow_redirects=True)

                # registro de usuario
                response = c.post(user_add_url,
                                  data=new_user_data,
                                  follow_redirects=True)
                self.assertStatus(response, 200)
                self.assertEqual('text/html; charset=utf-8',
                                 response.content_type)
                self.assert_template_used("forms/register.html")
                self.assertIn(expected_msg, response.data.decode('utf-8'))
                user = User.get_by_email(new_user_data['email'])
                self.assertIsInstance(user, User)
예제 #5
0
 def test_user_edit(self):
     """Test para la vista user_edit"""
     user_data = {
         'email': '*****@*****.**',
         'password': '******',
     }
     create_user(user_data['email'], user_data['password'], True)
     login_url = url_for('main.login')
     with current_app.app_context():
         with self.client as c:
             # login de usuario
             login_response = c.post(login_url,
                                     data=user_data,
                                     follow_redirects=True)
             self.assertStatus(login_response, 200)
             # vista user_edit
             user = User.get_by_email(user_data['email'])
             user_edit_url = url_for('main.user_edit', user_id=user.id)
             response = c.get(user_edit_url)
             self.assertStatus(response, 200)
             self.assertEqual('text/html; charset=utf-8',
                              response.content_type)
             self.assertEqual([i.url for i in current_breadcrumbs],
                              ['/', '/usuarios', user_edit_url])
             self.assert_template_used("forms/register.html")
             context_form = self.get_context_variable('form')
             self.assertIsInstance(context_form, forms.RegistrationForm)
예제 #6
0
    def test_reset_with_valid_token_update_ok(self):
        """Test de recuperación de contraseña"""
        user_data = {
            'email': '*****@*****.**',
            'password': '******',
        }
        create_user(user_data['email'], user_data['password'], True)
        reset_url = url_for('main.reset')

        with current_app.app_context():
            with self.client as c:
                with mail.record_messages() as outbox:
                    c.post(reset_url, data=user_data, follow_redirects=True)
                    # Obtenemos url del correo
                    email_msg = outbox[0]
                    links_found = url_pattern.findall(email_msg.html)
                    self.assertGreaterEqual(1, len(links_found))
                    reset_url_with_token = [
                        url for url in links_found if reset_url in url
                    ]
                    self.assertEqual(1, len(reset_url_with_token))
                    reset_url_with_token = reset_url_with_token[0]
                    # Llamamos a la vista reset_with_token con la contraseña
                    new_password = '******'
                    response = c.post(reset_url_with_token,
                                      data={
                                          'password': new_password,
                                          'confirm': new_password
                                      },
                                      follow_redirects=True)
                    self.assertStatus(response, 200)
                    self.assertTemplateUsed('auth/login.html')
                    user = User.get_by_email(user_data['email'])
                    self.assertTrue(user.check_password_hash(new_password))
예제 #7
0
def reset_with_token(token):
    try:
        ts = get_timed_serializer()
        email = ts.loads(token,
                         salt=current_app.config.get('TOKEN_EMAIL_SALT'),
                         max_age=current_app.config.get('TOKEN_MAX_AGE'))
    except Exception:
        abort(404, _('Token inválido'))

    form = PasswordForm()
    if request.method == 'POST' and form.validate():
        user = User.get_by_email(email)
        if not user.email_confirmed:
            user.send_confirmation_email()
            return render_template('auth/unconfirmed_email.html')

        controllers.set_user_password(user, form.password.data)
        flash(_('Nueva contraseña guardada con éxito!'), 'success')
        return redirect(url_for('.index'))

    data = {
        'form': form,
        'token': token
    }
    return render_template('auth/reset_with_token.html', **data)
예제 #8
0
def reset():
    form = EmailForm()

    if request.method == 'POST' and form.validate():
        user = User.get_by_email(form.email.data)
        if not user:
            flash(_('Usuario no registrado'), 'error')
            return render_template('auth/reset.html', form=form)
        if not user.email_confirmed:
            user.send_confirmation_email()
            return render_template('auth/unconfirmed_email.html')

        was_sent, error_msg = user.send_reset_password_email()
        if was_sent:
            flash(_('Se enviaron instrucciones para recuperar su contraseña '
                    'al correo: %(email)s', email=user.email), 'info')
        else:
            flash(_('Ocurrió un problema al enviar el correo con las '
                    'instrucciones de recuperación de contraseña a la '
                    'dirección: %(email)s. Erro: %(error)s',
                    email=user.email,
                    error=error_msg),
                  'error')

        return redirect(url_for('.index'))

    return render_template('auth/reset.html', form=form)
예제 #9
0
    def test_user_edit_update_raise_value_error(self):
        """Test para actualizar un usuario"""
        user_data = {
            'email': '*****@*****.**',
            'password': '******',
        }
        create_user(user_data['email'], user_data['password'], True)
        user = User.get_by_email(user_data['email'])
        login_url = url_for('main.login')

        with current_app.app_context():
            with self.client as c:
                with patch('biblat_manager.webapp.models.User'
                           '.send_confirmation_email') as mock:
                    mock.side_effect = ValueError(
                        'recipient_email es inválido!')
                    # login de usuario
                    c.post(login_url, data=user_data, follow_redirects=True)

                    # edición de usuario
                    user_data_update = {}
                    user_data_update.update(user_data)
                    user_data_update.update({
                        'email': '*****@*****.**',
                        'username': '******',
                        'password': '******',
                        'confirm': 'Quxquuxc0rge$'
                    })
                    user_edit_url = url_for('main.user_edit', user_id=user.id)
                    response = c.post(user_edit_url,
                                      data=user_data_update,
                                      follow_redirects=True)
                    self.assertRaises(ValueError)
                    self.assertStatus(response, 200)
                    self.assertEqual('text/html; charset=utf-8',
                                     response.content_type)
                    self.assert_template_used("forms/register.html")
                    expected_error_msg = 'Ocurrió un error en el envío del ' \
                                         'correo de confirmación  a: %s' % \
                                         user_data_update['email']
                    self.assertIn(expected_error_msg,
                                  response.data.decode('utf-8'))
                    updated_user = User.get_by_id(user.id)
                    self.assertEqual(user_data_update['email'],
                                     updated_user.email)
예제 #10
0
    def test_user_add_insert_one_with_confirmation_email(self):
        """Test para registro de un usuario con confirmación de correo"""
        user_data = {
            'email': '*****@*****.**',
            'password': '******',
        }
        new_user_data = {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'confirm': 'F00barbaz$'
        }
        create_user(user_data['email'], user_data['password'], True)
        login_url = url_for('main.login')
        logout_url = url_for('main.logout')
        user_add_url = (url_for('main.user_add'))
        expected_email = {
            'subject': 'Confirmación de correo electrónico',
            'recipients': [new_user_data['email']],
        }
        with current_app.app_context():
            with self.client as c:
                with mail.record_messages() as outbox:
                    # login de usuario
                    c.post(login_url, data=user_data, follow_redirects=True)

                    # registro de usuario
                    c.post(user_add_url,
                           data=new_user_data,
                           follow_redirects=True)
                    # logout de usuario
                    c.get(logout_url)
                    # confirmación de correo electrónico
                    email_msg = outbox[0]
                    self.assertEqual(1, len(outbox))
                    self.assertEqual(expected_email['subject'],
                                     email_msg.subject)
                    self.assertEqual(expected_email['recipients'],
                                     email_msg.recipients)
                    links_found = url_pattern.findall(email_msg.html)
                    self.assertGreaterEqual(1, len(links_found))
                    confirm_url_with_token = [
                        url for url in links_found if '/user/confirm/' in url
                    ]
                    self.assertEqual(1, len(confirm_url_with_token))
                    confirm_url_with_token = confirm_url_with_token[0]
                    # activamos correo electrónico
                    response = c.get(confirm_url_with_token,
                                     follow_redirects=True)
                    self.assertStatus(response, 200)
                    self.assertEqual('text/html; charset=utf-8',
                                     response.content_type)
                    self.assert_template_used("auth/login.html")
                    user = User.get_by_email(new_user_data['email'])
                    self.assertTrue(user.email_confirmed)
예제 #11
0
    def test_user_edit_duplicated_email(self):
        """Test para registro de un usuario"""
        user_data = {
            'email': '*****@*****.**',
            'password': '******',
        }

        create_user(user_data['email'], user_data['password'], True)
        create_user('*****@*****.**', 'F00barbaz$', True)
        user = User.get_by_email(user_data['email'])
        login_url = url_for('main.login')

        expected_error_msg = 'El correo electrónico ya esta registrado'
        with current_app.app_context():
            with self.client as c:
                # login de usuario
                c.post(login_url, data=user_data, follow_redirects=True)

                # edición de usuario
                user_data_update = {}
                user_data_update.update(user_data)
                user_data_update.update({
                    'email': '*****@*****.**',
                    'username': '******',
                    'password': '******',
                    'confirm': 'Quxquuxc0rge$'
                })
                user_edit_url = url_for('main.user_edit', user_id=user.id)
                response = c.post(user_edit_url,
                                  data=user_data_update,
                                  follow_redirects=True)
                self.assertStatus(response, 200)
                self.assertEqual('text/html; charset=utf-8',
                                 response.content_type)
                self.assert_template_used("forms/register.html")
                self.assertIn(expected_error_msg,
                              response.data.decode('utf-8'))
                updated_user = User.get_by_id(user.id)
                self.assertEqual(user_data['email'], updated_user.email)
예제 #12
0
def confirm_email(token):
    try:
        ts = get_timed_serializer()
        email = ts.loads(token,
                         salt=current_app.config.get('TOKEN_EMAIL_SALT'),
                         max_age=current_app.config.get('TOKEN_MAX_AGE'))
    except Exception:  # posibles exepciones: https://pythonhosted.org/itsdangerous/#exceptions
        abort(404)

    user = User.get_by_email(email)
    if not user:
        abort(404, _('Usuario no encontrado'))

    controllers.set_user_email_confirmed(user)
    flash(_('Email: %(email)s confirmado com éxito!', email=user.email), 'success')
    return redirect(url_for('.index'))
예제 #13
0
def login():
    if current_user.is_authenticated:
        return redirect(url_for('.index'))
    form = LoginForm()
    if request.method == 'POST' and form.validate():
        user = User.objects(email=form.email.data).first()
        if user and user.check_password_hash(form.password.data) \
                and user.email_confirmed:
            login_user(user, remember=form.remember.data)
            flash(_('Sesión iniciada como %s' % user.email), 'success')
            return redirect(session.get('next') or url_for('.index'))
        if not user:
            flash(_('Usuario no registrado'), 'error')
        if user and not user.check_password_hash(form.password.data):
            flash(_('Contraseña incorrecta'), 'error')
        if user and not user.email_confirmed:
            flash(_('Correo electrónico no verificado'), 'error')
    return render_template('auth/login.html', form=form)
예제 #14
0
    def test_user_add_insert_one_raise_value_error(self):
        """Test para registro de un usuario"""
        user_data = {
            'email': '*****@*****.**',
            'password': '******',
        }
        new_user_data = {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'confirm': 'F00barbaz$'
        }
        create_user(user_data['email'], user_data['password'], True)
        login_url = url_for('main.login')
        user_add_url = (url_for('main.user_add'))
        expected_error_msg = 'Ocurrió un error en el envío del correo de ' \
                             'confirmación  a: %s' % new_user_data['email']
        with current_app.app_context():
            with self.client as c:
                with patch('biblat_manager.webapp.models.User'
                           '.send_confirmation_email') as mock:
                    mock.side_effect = ValueError(
                        'recipient_email es inválido!')
                    # login de usuario
                    c.post(login_url, data=user_data, follow_redirects=True)

                    # registro de usuario
                    response = c.post(user_add_url,
                                      data=new_user_data,
                                      follow_redirects=True)
                    self.assertRaises(ValueError)
                    self.assertStatus(response, 200)
                    self.assertEqual('text/html; charset=utf-8',
                                     response.content_type)
                    self.assert_template_used("forms/register.html")
                    self.assertIn(expected_error_msg,
                                  response.data.decode('utf-8'))
                    user = User.get_by_email(new_user_data['email'])
                    self.assertIsInstance(user, User)
예제 #15
0
def user_detail(user_id):
    user = User.get_by_id(user_id)
    data = {
        'user': user
    }
    return render_template('main/user.html', **data)