Example #1
0
    def test_failed_login_with_api_error(self, mocked):

        # get a valid login link/provider
        providers = OAuthProvider()
        valid_providers = providers.get_slugs()
        self.assertTrue(valid_providers)

        # error in HTML and parsed
        html = """
        <html>
            <head>
                <title>Error Page</title>
            </head>
            <body>
                <div class="error">
                    <h1>Ooops...</h1>
                    <p>Error message</p>
                </div>
            </body>
        </html>
        """
        parsed = 'Error Page Ooops... Error message'

        # create a mock object for Authomatic.login()
        mocked.return_value = MockAuthomatic(error=html)

        # login & assert welcome message was shown
        resp1 = self.app.get('/login/{}'.format(valid_providers[0]),
                             follow_redirects=True)
        self.assertIn(parsed, resp1.data, 'API message does not match')
Example #2
0
    def test_new_user_login(self, mocked):

        # get a valid login link/provider
        providers = OAuthProvider()
        valid_providers = providers.get_slugs()
        self.assertTrue(valid_providers)

        # create a mock object for Authomatic.login()
        mocked.return_value = MockAuthomatic()

        # assert that we have no users in the database
        self.assertEqual(db.session.query(User).count(), 0,
                         'User count before login differs than 0')
        self.app.get('/login/{}'.format(valid_providers[0]))

        # assert a user was created
        self.assertEqual(db.session.query(User).count(), 1,
                         'User count after login differs than 1')

        # assert user data
        u = User.query.first()
        self.assertEqual(u.email, '*****@*****.**', "Emails don't match")
        self.assertEqual(u.name, 'John Doe', "Name doesn't match")
        self.assertEqual(u.created_at, u.last_seen, "Time doesn't match")
        self.assertEqual(u.group.title, 'user')
        self.assertTrue(u.last_seen, "Last seen is blank")
        self.assertEqual(u.created_with, valid_providers[0],
                         "Provider doesn't match")
Example #3
0
    def test_returning_user_with_remember_me(self, mocked):

        # get a valid login link/provider
        providers = OAuthProvider()
        valid_providers = providers.get_slugs()
        self.assertTrue(valid_providers)

        # create a mock object for Authomatic.login()
        mocked.return_value = MockAuthomatic()

        # create user and token
        user = User(email='*****@*****.**')
        user.remember_me_token = user.get_token()
        db.session.add(user)
        db.session.commit()

        # create cookies
        self.app.set_cookie('localhost', 'user_id', '1')
        self.app.set_cookie('localhost', 'remember_me', user.get_hash())

        # assert user is logged in
        resp = self.app.get('/')
        self.assertIn('href="/logout"', resp.data)
        self.assertNotIn('href="/login', resp.data)

        # clean cookis for next sessions
        self.app.delete_cookie('localhost', 'user_id')
        self.app.delete_cookie('localhost', 'remember_me')
Example #4
0
    def test_login_with_remember_me(self, mocked):

        # get a valid login link/provider
        providers = OAuthProvider()
        valid_providers = providers.get_slugs()
        self.assertTrue(valid_providers)

        # create a mock object for Authomatic.login()
        mocked.return_value = MockAuthomatic()

        # create new user
        self.app.delete_cookie('localhost', 'user_id')
        self.app.delete_cookie('localhost', 'remember_me')
        self.app.post('/login/process',
                      follow_redirects=True,
                      data={'remember_me': '1',
                            'provider': valid_providers[0]})

        # assert cookies were created accordingly
        user = User.query.first()
        self.assertEqual(user.id, int(self.read_cookie('user_id')))
        self.assertTrue(user.check_hash(self.read_cookie('remember_me')))

        # clean cookis for next sessions
        self.app.delete_cookie('localhost', 'user_id')
        self.app.delete_cookie('localhost', 'remember_me')
Example #5
0
    def test_returning_user_login(self, mocked):

        # get a valid login link/provider
        providers = OAuthProvider()
        valid_providers = providers.get_slugs()
        self.assertTrue(valid_providers)

        # create a mock object for Authomatic.login()
        mocked.return_value = MockAuthomatic()

        # login & assert welcome message was shown
        resp1 = self.app.get('/login/{}'.format(valid_providers[0]),
                             follow_redirects=True)
        self.assertIn('Welcome, John Doe', resp1.data,
                      'No welcome message found after login')

        # logout & assert logout message was shown
        resp2 = self.app.get('/logout', follow_redirects=True)
        self.assertIn('You\'ve been logged out', resp2.data,
                      'No logout message found after logout')

        # login again & assert only one user was created
        self.app.get('/login/{}'.format(valid_providers[0]))
        u = User.query.first()
        self.assertEqual(u.email, '*****@*****.**', "Emails don't match")
        self.assertEqual(u.name, 'John Doe', "Name doesn't match")
        self.assertNotEqual(u.created_at, u.last_seen,
                            "Last seen wasn't updated")
        self.assertEqual(db.session.query(User).count(), 1,
                         'User count after login differs than 1')
Example #6
0
    def test_login_providers(self):

        # test if links to the ouauth/oauth2 providers (20X or 30X)
        providers = OAuthProvider()
        for provider in providers.get_slugs():
            resp = self.app.get('/login/{}'.format(provider))
            self.assertEqual(resp.status_code, 302)

        # test if unauthorized provider returns 404
        resp = self.app.get('/login/anything_else')
        self.assertEqual(resp.status_code, 404)
Example #7
0
    def test_login_pages(self):

        # test if login page exists
        resp = self.app.get('/login')
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(resp.mimetype, 'text/html')

        # test if are there links to oauth/oauth2 providers
        providers = OAuthProvider()
        for provider in providers.get_slugs():
            self.assertIn(' data-oauth="{}"'.format(provider), resp.data)

        # test if is there a link to login in the home page
        resp = self.app.get('/')
        self.assertIn('href="/login', resp.data)
Example #8
0
    def test_unsuccessful_user_login_with_no_email(self, mocked):

        # get a valid login link/provider
        providers = OAuthProvider()
        valid_providers = providers.get_slugs()
        self.assertTrue(valid_providers)

        # create a mock object for Authomatic.login() & try to login
        mocked.return_value = MockAuthomatic(email=None)
        resp = self.app.get('/login/{}'.format(valid_providers[0]),
                            follow_redirects=True)

        # assert error message was shown
        self.assertIn('refusing to send us your email address', resp.data,
                      'No error shown after trying login without email')

        # assert that we have no users in the database
        self.assertEqual(db.session.query(User).count(), 0,
                         'User count after login differs than 0')
Example #9
0
    def test_new_admin_user_login(self, mocked):

        # get a valid login link/provider
        providers = OAuthProvider()
        valid_providers = providers.get_slugs()
        self.assertTrue(valid_providers)

        # random pick an admin email from the config
        admin_email = random_choice(app.config['ADMIN'])

        # create a mock object for Authomatic.login()
        mocked.return_value = MockAuthomatic(email=admin_email)

        # create a new admin user
        self.app.get('/login/{}'.format(valid_providers[0]))

        # assert the new user is an admin
        u = User.query.first()
        self.assertEqual(u.group.title, 'admin')
Example #10
0
def login(provider):

    # after login url
    next_page = 'site.index'

    # check if provider is valid
    providers = OAuthProvider()
    if provider not in providers.get_slugs():
        abort(404)

    # create authomatic and response objects
    authomatic = Authomatic(providers.credentials,
                            app.config['SECRET_KEY'],
                            report_errors=True)
    oauth_response = make_response()

    # try login
    provider_name = providers.get_name(provider)
    adapter = WerkzeugAdapter(request, oauth_response)
    result = authomatic.login(adapter, provider_name)
    if result:

        # flash error message if any
        if result.error and app.debug:
            session['remember_me'] = False
            session['provider'] = None
            msg = BeautifulSoup(result.error.message).findAll(text=True)
            flash({'type': 'alert', 'text': ' '.join(msg)})

        # if success
        redir_resp = make_response(redirect(url_for(next_page)))
        if result.user:
            result.user.update()

            # check if api sent email address
            if not result.user.email:
                msg = '{} is refusing to send us your email address. '
                msg += 'Please, try another log in provider.'
                flash({'type': 'error', 'text': msg.format(provider_name)})
                next_page = 'site.login_options'

            # manage user data in db
            else:

                # convert all emails to lowercase (avoids duplicity in db)
                result.user.email = result.user.email.lower()

                # if existing user
                user = User.query.filter_by(email=result.user.email).first()
                if user:
                    if provider != user.created_with:
                        return redirect('/login/{}'.format(user.created_with))
                    user.last_seen = datetime.now()
                    db.session.add(user)
                    db.session.commit()

                # if new user
                else:
                    now = datetime.now()
                    roles = Group()
                    if result.user.email in app.config['ADMIN']:
                        role = roles.default('admin')
                    else:
                        role = roles.default()
                    new_user = User(email=result.user.email,
                                    name=result.user.name,
                                    created_with=provider,
                                    created_at=now,
                                    last_seen=now,
                                    group=role)
                    # check if email address is valid
                    if not new_user.valid_email():
                        msg = 'The address “{}” provided by {} is not a valid '
                        msg += 'email. Please, try another log in provider.'
                        flash({
                            'type': 'error',
                            'text': msg.format(new_user.email, provider_name)
                        })
                        next_page = 'site.login_options'

                    # save user to db
                    else:
                        db.session.add(new_user)
                        db.session.commit()
                        new_query = User.query.filter_by(email=new_user.email)
                        user = new_query.first()

                # login user
                if user and user.valid_email():
                    login_user(user)
                    flash({
                        'type': 'success',
                        'text': 'Welcome, {}'.format(result.user.name)
                    })
                # remember me
                remember_me = session.get('remember_me', False)
                if remember_me:
                    session_provider = session.get('provider', False)
                    if provider == session_provider:
                        session['remember_me'] = False
                        session['provider'] = None
                        user.remember_me_token = user.get_token()
                        db.session.add(user)
                        db.session.commit()
                        max_age = 60 * 60 * 24 * 30
                        redir_resp.set_cookie('remember_me',
                                              user.get_hash(),
                                              max_age=max_age)
                        redir_resp.set_cookie('user_id',
                                              str(user.id),
                                              max_age=max_age)

        return redir_resp

    return oauth_response
Example #11
0
def login_options():
    return render_template('login.slim',
                           page_title='Log in',
                           providers=OAuthProvider(),
                           form=LoginForm())
Example #12
0
def login(provider):

    # after login url
    next_page = 'site.index'

    # check if provider is valid
    providers = OAuthProvider()
    if provider not in providers.get_slugs():
        abort(404)

    # create authomatic and response objects
    authomatic = Authomatic(providers.credentials,
                            app.config['SECRET_KEY'],
                            report_errors=True)
    oauth_response = make_response()

    # try login
    provider_name = providers.get_name(provider)
    adapter = WerkzeugAdapter(request, oauth_response)
    result = authomatic.login(adapter, provider_name)
    if result:

        # flash error message if any
        if result.error and app.debug:
            session['remember_me'] = False
            session['provider'] = None
            msg = BeautifulSoup(result.error.message).findAll(text=True)
            flash({'type': 'alert', 'text': ' '.join(msg)})

        # if success
        redir_resp = make_response(redirect(url_for(next_page)))
        if result.user:
            result.user.update()

            # check if api sent email address
            if not result.user.email:
                msg = '{} is refusing to send us your email address. '
                msg += 'Please, try another log in provider.'
                flash({'type': 'error', 'text': msg.format(provider_name)})
                next_page = 'site.login_options'

            # manage user data in db
            else:

                # convert all emails to lowercase (avoids duplicity in db)
                result.user.email = result.user.email.lower()

                # if existing user
                user = User.query.filter_by(email=result.user.email).first()
                if user:
                    if provider != user.created_with:
                        return redirect('/login/{}'.format(user.created_with))
                    user.last_seen = datetime.now()
                    db.session.add(user)
                    db.session.commit()

                # if new user
                else:
                    now = datetime.now()
                    roles = Group()
                    if result.user.email in app.config['ADMIN']:
                        role = roles.default('admin')
                    else:
                        role = roles.default()
                    new_user = User(email=result.user.email,
                                    name=result.user.name,
                                    created_with=provider,
                                    created_at=now,
                                    last_seen=now,
                                    group=role)
                    # check if email address is valid
                    if not new_user.valid_email():
                        msg = 'The address “{}” provided by {} is not a valid '
                        msg += 'email. Please, try another log in provider.'
                        flash({'type': 'error',
                               'text': msg.format(new_user.email,
                                                  provider_name)})
                        next_page = 'site.login_options'

                    # save user to db
                    else:
                        db.session.add(new_user)
                        db.session.commit()
                        new_query = User.query.filter_by(email=new_user.email)
                        user = new_query.first()

                # login user
                if user and user.valid_email():
                    login_user(user)
                    flash({'type': 'success',
                           'text': 'Welcome, {}'.format(result.user.name)})
                # remember me
                remember_me = session.get('remember_me', False)
                if remember_me:
                    session_provider = session.get('provider', False)
                    if provider == session_provider:
                        session['remember_me'] = False
                        session['provider'] = None
                        user.remember_me_token = user.get_token()
                        db.session.add(user)
                        db.session.commit()
                        max_age = 60 * 60 * 24 * 30
                        redir_resp.set_cookie('remember_me',
                                              user.get_hash(),
                                              max_age=max_age)
                        redir_resp.set_cookie('user_id',
                                              str(user.id),
                                              max_age=max_age)

        return redir_resp

    return oauth_response
Example #13
0
from findaconf.helpers.providers import OAuthProvider
from flask.ext.wtf import Form
from wtforms import BooleanField, HiddenField
from wtforms.validators import AnyOf

providers = OAuthProvider()


class LoginForm(Form):
    remember_me = BooleanField('Remember me (for a month)')
    provider = HiddenField(default='google-plus',
                           validators=[AnyOf(providers.get_slugs())])