def test_logged_social_connect_account(social_config, active_user, db_session):
    """Connect facebook account to logged in user."""
    user = db_session.merge(active_user)

    profile = {
        'accounts': [{'domain': text_type('facebook.com'), 'userid': text_type('2343')}],
        'displayName': text_type('teddy'),
        'preferredUsername': text_type('teddy'),
        'emails': [{'value': text_type('*****@*****.**')}],
        'name': text_type('ted')
    }
    credentials = {'oauthAccessToken': '7897048593434'}
    provider_name = text_type('facebook')
    provider_type = text_type('facebook')
    request = testing.DummyRequest()
    request.user = user
    request.registry = social_config.registry
    request.remote_addr = text_type('127.0.0.123')
    request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)
    request._ = mock_translate

    request.login_perform = MagicMock(name='login_perform')
    request.login_perform.return_value = {'status': True}
    view = SocialLoginViews(request)
    out = view()
    assert out['status'] is True

    transaction.commit()
    user = db_session.merge(user)
    assert user.provider_id(text_type('facebook')) == profile['accounts'][0]['userid']
Exemple #2
0
def main():
    config = Configurator()

    engine = create_engine('sqlite:///foo.db')

    DBSession.configure(bind=engine)

    Base.metadata.drop_all(engine)
    Base.metadata.create_all(engine)

    user1 = User(username=text_type('sontek'))

    profile = UserProfile(user=user1, first_name=text_type('John'))

    DBSession.add_all([user1, profile])

    cache_settings = {
        "cache.redis.backend": "dogpile.cache.redis",
        "cache.redis.arguments.host": "localhost",
        "cache.redis.arguments.port": 6379,
    }

    cache_region.configure_from_config(cache_settings, "cache.redis.")

    config.add_view(hello_world)
    app = config.make_wsgi_app()

    return app
def test_social_login_register(social_config, db_session):
    """Register fresh user and logs him in."""
    profile = {
        'accounts': [{'domain': text_type('facebook.com'), 'userid': text_type('2343')}],
        'displayName': text_type('teddy'),
        'verifiedEmail': text_type('*****@*****.**'),
        'preferredUsername': text_type('teddy'),
        'emails': [{'value': text_type('*****@*****.**')}],
        'name': text_type('ted')
    }
    credentials = {'oauthAccessToken': '7897048593434'}
    provider_name = text_type('facebook')
    provider_type = text_type('facebook')
    request = testing.DummyRequest()
    request.user = None
    request.registry = social_config.registry
    request.remote_addr = text_type('127.0.0.123')
    request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)

    request.login_perform = MagicMock(name='login_perform')
    request.login_perform.return_value = {'status': True}
    view = SocialLoginViews(request)
    out = view()
    assert out == {'status': True}
    transaction.commit()

    # read first new account
    user = db_session.query(User).one()
    assert user.is_active
    assert user.provider_id('facebook') == profile['accounts'][0]['userid']
def test_social_login_register(social_config, db_session):
    """Register fresh user and logs him in."""
    profile = {
        'accounts': [{'domain': text_type('facebook.com'), 'userid': text_type('2343')}],
        'displayName': text_type('teddy'),
        'verifiedEmail': text_type('*****@*****.**'),
        'preferredUsername': text_type('teddy'),
        'emails': [{'value': text_type('*****@*****.**')}],
        'name': text_type('ted')
    }
    credentials = {'oauthAccessToken': '7897048593434'}
    provider_name = text_type('facebook')
    provider_type = text_type('facebook')
    request = testing.DummyRequest()
    request.user = None
    request.registry = social_config.registry
    request.remote_addr = text_type('127.0.0.123')
    request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)

    request.login_perform = MagicMock(name='login_perform')
    request.login_perform.return_value = {'status': True}
    view = SocialLoginViews(request)
    out = view()
    assert out == {'status': True}
    transaction.commit()

    # read first new account
    user = db_session.query(User).one()
    assert user.is_active
    assert user.provider_id('facebook') == profile['accounts'][0]['userid']
def test_login_different_social_account(social_config, db_session, facebook_user):  # pylint:disable=unused-argument
    """
    Login with different social account than connected from same provider.

    System should let user in, but not change connection.
    """
    # profile mock response
    profile = {
        # facebook user id is different than user's
        'accounts': [{'domain': text_type('facebook.com'), 'userid': text_type('2343')}],
        'displayName': text_type('teddy'),
        'verifiedEmail': facebook_user.email,
        'preferredUsername': text_type('teddy'),
        'emails': [{'value': text_type('*****@*****.**')}],
        'name': text_type('ted')
    }
    request = testing.DummyRequest()
    request.user = None
    request.registry = social_config.registry
    request.remote_addr = text_type('127.0.0.123')
    request.context = AuthenticationComplete(
        profile,
        {'oauthAccessToken': '7897048593434'},
        text_type('facebook'),
        text_type('facebook'))

    request.login_perform = MagicMock(name='login_perform')
    request.login_perform.return_value = {'status': True}
    view = SocialLoginViews(request)
    out = view()
    # user should be authenticated recognized by email!
    assert out['status'] is True
    assert facebook_user.provider_id(text_type('facebook')) is not profile['accounts'][0]['userid']
def test_aftersociallogin(aftersociallogin_config, db_session):  # pylint:disable=redefined-outer-name
    """Register fresh user and logs him in and check response if redirect from AfterSocialLogIn."""
    profile = {
        'accounts': [{'domain': text_type('facebook.com'), 'userid': text_type('2343')}],
        'displayName': text_type('teddy'),
        'verifiedEmail': text_type('*****@*****.**'),
        'preferredUsername': text_type('teddy'),
        'emails': [{'value': text_type('*****@*****.**')}],
        'name': text_type('ted')
    }
    credentials = {'oauthAccessToken': '7897048593434'}
    provider_name = text_type('facebook')
    provider_type = text_type('facebook')
    request = testing.DummyRequest()
    request.user = None
    request.registry = aftersociallogin_config.registry
    request.remote_addr = text_type('127.0.0.123')
    request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)

    def login_perform(*_, **kwargs):
        return HTTPFound(location=kwargs['location'])
    request.login_perform = login_perform
    view = SocialLoginViews(request)
    out = view()
    assert out.location == EVENT_PATH.format(AfterSocialLogIn)
    transaction.commit()

    # read first new account
    user = db_session.query(User).one()
    assert user.is_active
    assert user.provider_id('facebook') == profile['accounts'][0]['userid']
def test_password_empty(db_with_user):
    """User::empty password change"""

    user = db_with_user.query(User).filter(User.username == text_type("u1")).one()

    with pytest.raises(EmptyError):
        user.password = text_type("")
def test_social_login_register(social_config, db_session):
    """Register fresh user and logs him in."""
    profile = {
        "accounts": [{"domain": text_type("facebook.com"), "userid": text_type("2343")}],
        "displayName": text_type("teddy"),
        "verifiedEmail": text_type("*****@*****.**"),
        "preferredUsername": text_type("teddy"),
        "emails": [{"value": text_type("*****@*****.**")}],
        "name": text_type("ted"),
    }
    credentials = {"oauthAccessToken": "7897048593434"}
    provider_name = text_type("facebook")
    provider_type = text_type("facebook")
    request = testing.DummyRequest()
    request.user = None
    request.registry = social_config.registry
    request.remote_addr = text_type("127.0.0.123")
    request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)

    request.login_perform = MagicMock(name="login_perform")
    request.login_perform.return_value = {"status": True}
    view = SocialLoginViews(request)
    out = view()
    assert out == {"status": True}
    transaction.commit()

    # read first new account
    user = db_session.query(User).one()
    assert user.is_active
    assert user.provider_id("facebook") == profile["accounts"][0]["userid"]
Exemple #9
0
def test_aftersociallogin(aftersociallogin_config, aftersociallogin_app, db_session):
    """Register fresh user and logs him in and check response if redirect from AfterSocialLogIn."""
    profile = {
        'accounts': [{'domain': text_type('facebook.com'), 'userid': text_type('2343')}],
        'displayName': text_type('teddy'),
        'verifiedEmail': text_type('*****@*****.**'),
        'preferredUsername': text_type('teddy'),
        'emails': [{'value': text_type('*****@*****.**')}],
        'name': text_type('ted')
    }
    credentials = {'oauthAccessToken': '7897048593434'}
    provider_name = text_type('facebook')
    provider_type = text_type('facebook')
    request = testing.DummyRequest()
    request.user = None
    request.registry = aftersociallogin_config.registry
    request.remote_addr = text_type('127.0.0.123')
    request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)

    def login_perform(*args, **kwargs):
        return HTTPFound(location=kwargs['location'])
    request.login_perform = login_perform
    view = SocialLoginViews(request)
    out = view()
    assert out.location == EVENT_PATH.format(AfterSocialLogIn)
    transaction.commit()

    # read first new account
    user = db_session.query(User).one()
    assert user.is_active
    assert user.provider_id('facebook') == profile['accounts'][0]['userid']
def test_change_email(db_with_user):
    '''User::change_email'''
    user = db_with_user.query(User).filter(User.email == text_type('*****@*****.**')).one()
    user.set_new_email(text_type('*****@*****.**'))
    user.change_email()

    assert not user.email_change_key
Exemple #11
0
def db_locales(db_session):
    """Add Languages to db_session."""
    for locale in ['pl', 'cz', 'fr']:
        locale_object = Language(name=text_type(locale),
                                 native_name=text_type(locale),
                                 language_code=text_type(locale))
        db_session.add(locale_object)
    transaction.commit()
Exemple #12
0
def db_locales(db_session):  # pylint:disable=redefined-outer-name
    """Add Languages to db_session."""
    for locale in ['pl', 'cz', 'fr']:
        locale_object = Language(name=text_type(locale),
                                 native_name=text_type(locale),
                                 language_code=text_type(locale))
        db_session.add(locale_object)
    transaction.commit()
def test_logged_social_connect_account(social_config, active_user, db_session):
    """Connect facebook account to logged in user."""
    user = db_session.merge(active_user)

    profile = {
        "accounts": [{"domain": text_type("facebook.com"), "userid": text_type("2343")}],
        "displayName": text_type("teddy"),
        "preferredUsername": text_type("teddy"),
        "emails": [{"value": text_type("*****@*****.**")}],
        "name": text_type("ted"),
    }
    credentials = {"oauthAccessToken": "7897048593434"}
    provider_name = text_type("facebook")
    provider_type = text_type("facebook")
    request = testing.DummyRequest()
    request.user = user
    request.registry = social_config.registry
    request.remote_addr = text_type("127.0.0.123")
    request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)
    request._ = mock_translate

    request.login_perform = MagicMock(name="login_perform")
    request.login_perform.return_value = {"status": True}
    view = SocialLoginViews(request)
    out = view()
    assert out["status"] is True

    transaction.commit()
    user = db_session.merge(user)
    assert user.provider_id("facebook") == profile["accounts"][0]["userid"]
def test_login_different_social_account(social_config, db_session, facebook_user):
    """
    Login with different social account than connected from same provider.

    System should let user in, but not change connection.
    """
    # profile mock response
    profile = {
        # facebook user id is different than user's
        'accounts': [{'domain': text_type('facebook.com'), 'userid': text_type('2343')}],
        'displayName': text_type('teddy'),
        'verifiedEmail': facebook_user.email,
        'preferredUsername': text_type('teddy'),
        'emails': [{'value': text_type('*****@*****.**')}],
        'name': text_type('ted')
    }
    request = testing.DummyRequest()
    request.user = None
    request.registry = social_config.registry
    request.remote_addr = text_type('127.0.0.123')
    request.context = AuthenticationComplete(
        profile,
        {'oauthAccessToken': '7897048593434'},
        text_type('facebook'),
        text_type('facebook'))

    request.login_perform = MagicMock(name='login_perform')
    request.login_perform.return_value = {'status': True}
    view = SocialLoginViews(request)
    out = view()
    # user should be authenticated recognized by email!
    assert out['status'] is True
    assert facebook_user.provider_id('facebook') is not profile['accounts'][0]['userid']
def test_logged_social_connect_second_account(social_config, facebook_user, db_session):
    """Connect second facebook account to logged in user."""
    user = db_session.merge(facebook_user)

    # mock request
    profile = {
        "accounts": [{"domain": text_type("facebook.com"), "userid": text_type("2343")}],
        "displayName": text_type("teddy"),
        "preferredUsername": text_type("teddy"),
        "emails": [{"value": text_type("*****@*****.**")}],
        "name": text_type("ted"),
    }
    credentials = {"oauthAccessToken": "7897048593434"}
    provider_name = text_type("facebook")
    provider_type = text_type("facebook")
    request = testing.DummyRequest()
    request.user = user
    request.registry = social_config.registry
    request.remote_addr = text_type("127.0.0.123")
    request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)
    request._ = mock_translate

    request.login_perform = MagicMock(name="login_perform")
    request.login_perform.return_value = {"status": True}
    view = SocialLoginViews(request)
    out = view()
    # status should be false
    assert out["status"] is False
    assert out["msg"] == "Your account is already connected to other ${provider} account."
    assert user.provider_id("facebook") is not profile["accounts"][0]["userid"]
def test_logged_social_connect_account(social_config, active_user, db_session):
    """Connect facebook account to logged in user."""
    user = db_session.merge(active_user)

    profile = {
        'accounts': [{'domain': text_type('facebook.com'), 'userid': text_type('2343')}],
        'displayName': text_type('teddy'),
        'preferredUsername': text_type('teddy'),
        'emails': [{'value': text_type('*****@*****.**')}],
        'name': text_type('ted')
    }
    credentials = {'oauthAccessToken': '7897048593434'}
    provider_name = text_type('facebook')
    provider_type = text_type('facebook')
    request = testing.DummyRequest()
    request.user = user
    request.registry = social_config.registry
    request.remote_addr = text_type('127.0.0.123')
    request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)
    request._ = mock_translate

    request.login_perform = MagicMock(name='login_perform')
    request.login_perform.return_value = {'status': True}
    view = SocialLoginViews(request)
    out = view()
    assert out['status'] is True

    transaction.commit()
    user = db_session.merge(user)
    assert user.provider_id('facebook') == profile['accounts'][0]['userid']
def test_login_different_social_account(social_config, db_session, facebook_user):
    """
    Login with different social account than connected from same provider.

    System should let user in, but not change connection.
    """
    # profile mock response
    profile = {
        # facebook user id is different than user's
        "accounts": [{"domain": text_type("facebook.com"), "userid": text_type("2343")}],
        "displayName": text_type("teddy"),
        "verifiedEmail": facebook_user.email,
        "preferredUsername": text_type("teddy"),
        "emails": [{"value": text_type("*****@*****.**")}],
        "name": text_type("ted"),
    }
    request = testing.DummyRequest()
    request.user = None
    request.registry = social_config.registry
    request.remote_addr = text_type("127.0.0.123")
    request.context = AuthenticationComplete(
        profile, {"oauthAccessToken": "7897048593434"}, text_type("facebook"), text_type("facebook")
    )

    request.login_perform = MagicMock(name="login_perform")
    request.login_perform.return_value = {"status": True}
    view = SocialLoginViews(request)
    out = view()
    # user should be authenticated recognized by email!
    assert out["status"] is True
    assert facebook_user.provider_id("facebook") is not profile["accounts"][0]["userid"]
def test_email_from_context(profile, email):
    """Test email_from_context email getting method."""
    from velruse import AuthenticationComplete
    context = AuthenticationComplete(
        profile,
        {'oauthAccessToken': '7897048593434'},
        text_type('facebook'),
        text_type('facebook')
    )
    view = SocialLoginViews(mock.MagicMock())
    assert view._email_from_context(context) == email
    def setUp(self):
        '''
            setUp test method @see unittest.TestCase.setUp
        '''
        Base.metadata.create_all(engine)

        for locale in ['pl', 'cz', 'fr']:
            locale_object = Language(name=text_type(locale),
                                     native_name=text_type(locale),
                                     language_code=text_type(locale))
            Session.add(locale_object)
def test_email_from_context(profile, email):
    """Test email_from_context email getting method."""
    from velruse import AuthenticationComplete
    context = AuthenticationComplete(
        profile,
        {'oauthAccessToken': '7897048593434'},
        text_type('facebook'),
        text_type('facebook')
    )
    view = SocialLoginViews(mock.MagicMock())
    assert view._email_from_context(context) == email
Exemple #21
0
    def password_validator(self, key, password):
        """
        Validate password.

        Password validator keeps new password hashed.
        Rises Value error on empty password

        :param str key: field key
        :param str password: new password

        :returns: hashed and salted password
        :rtype: str
        :raises: pyramid_fullauth.exceptions.EmptyError

        .. note::

            If you're using this Mixin on your own User object,
            don't forget to add a listener as well, like that:

            .. code-block:: python

                from sqlalchemy.event import listen

                listen(User.password, 'set', User.password_listener, retval=True)

        .. note::

            For more information on Attribute Events in sqlalchemy see:

            :meth:`sqlalchemy.orm.events.AttributeEvents.set`

        """
        if not password:
            raise EmptyError('password-empty')

        # reading default hash_algorithm
        hash_algorithm = self.__class__._hash_algorithm.property.columns[
            0].default.arg

        # getting currently used hash method
        hash_method = getattr(hashlib, hash_algorithm)

        # generating salt
        salt = hash_method()
        salt.update(os.urandom(60))
        salt_value = salt.hexdigest()

        # storing used hash algorithm
        self._hash_algorithm = hash_algorithm
        self._salt = text_type(salt_value)
        return text_type(
            self.__class__.hash_password(password, salt_value, hash_method))
Exemple #22
0
    def password_validator(self, _, password):
        """
        Validate password.

        Password validator keeps new password hashed.
        Rises Value error on empty password

        :param str key: field key
        :param str password: new password

        :returns: hashed and salted password
        :rtype: str
        :raises: pyramid_fullauth.exceptions.EmptyError

        .. note::

            If you're using this Mixin on your own User object,
            don't forget to add a listener as well, like that:

            .. code-block:: python

                from sqlalchemy.event import listen

                listen(User.password, 'set', User.password_listener, retval=True)

        .. note::

            For more information on Attribute Events in sqlalchemy see:

            :meth:`sqlalchemy.orm.events.AttributeEvents.set`

        """
        if not password:
            raise EmptyError('password-empty')

        # reading default hash_algorithm
        # pylint:disable=protected-access
        hash_algorithm = self.__class__._hash_algorithm.property.columns[0].default.arg
        # pylint:enable=protected-access

        # getting currently used hash method
        hash_method = getattr(hashlib, hash_algorithm)

        # generating salt
        salt = hash_method()
        salt.update(os.urandom(60))
        salt_value = salt.hexdigest()

        # storing used hash algorithm
        self._hash_algorithm = hash_algorithm
        self._salt = text_type(salt_value)
        return text_type(self.__class__.hash_password(password, salt_value, hash_method))
    def test_email_valid_formats(self, db, email):
        ''' Check all valid formats of Email (RFC 5321) can be set by user
        '''
        self.create_user(db, username=text_type('u1'))

        user = db.query(User).filter(User.username == text_type('u1')).one()

        user.email = email
        db.commit()

        user = db.query(User).filter(
            User.username == text_type('u1')).one()
        assert user.email == email
    def test_email_invalid_formats(self, db, email):
        '''
        Check all invalid formats of Email (RFC 5321) can not be set by user
        '''

        self.create_user(db, username=text_type('u1'))

        user = db.query(User).filter(User.username == text_type('u1')).one()
        assert user.email == text_type('*****@*****.**')

        with pytest.raises(EmailValidationError):
            user.email = email
            db.commit()
def test_login_social_connect(social_config, active_user, db_session):
    """Connect and logs user in."""
    user = db_session.merge(active_user)

    profile = {
        "accounts": [{"domain": text_type("facebook.com"), "userid": text_type("2343")}],
        "displayName": text_type("teddy"),
        "preferredUsername": text_type("teddy"),
        "emails": [{"value": user.email}],
        "name": text_type("ted"),
    }
    credentials = {"oauthAccessToken": "7897048593434"}
    provider_name = text_type("facebook")
    provider_type = text_type("facebook")
    user = None
    request = testing.DummyRequest()
    request.user = user
    request.registry = social_config.registry
    request.remote_addr = text_type("127.0.0.123")
    request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)

    request.login_perform = MagicMock(name="login_perform")
    request.login_perform.return_value = {"status": True}
    view = SocialLoginViews(request)
    out = view()
    assert out == {"status": True}
def test_password_change(db_session, user, password):
    """User password change."""
    new_password = text_type(password)

    user = db_session.merge(user)
    old_password = user.password
    old_salt = user._salt
    user.password = new_password
    transaction.commit()

    user = db_session.query(User).filter(User.username == text_type('u1')).one()
    assert not user.password == old_password
    assert not user._salt == old_salt
    assert user.check_password(new_password)
def test_login_social_connect(social_config, active_user, db_session):
    """Connect and logs user in."""
    user = db_session.merge(active_user)

    profile = {
        'accounts': [{'domain': text_type('facebook.com'), 'userid': text_type('2343')}],
        'displayName': text_type('teddy'),
        'preferredUsername': text_type('teddy'),
        'emails': [{'value': user.email}],
        'name': text_type('ted')
    }
    credentials = {'oauthAccessToken': '7897048593434'}
    provider_name = text_type('facebook')
    provider_type = text_type('facebook')
    user = None
    request = testing.DummyRequest()
    request.user = user
    request.registry = social_config.registry
    request.remote_addr = text_type('127.0.0.123')
    request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)

    request.login_perform = MagicMock(name='login_perform')
    request.login_perform.return_value = {'status': True}
    view = SocialLoginViews(request)
    out = view()
    assert out == {'status': True}
def test_login_social_connect(social_config, active_user, db_session):
    """Connect and logs user in."""
    user = db_session.merge(active_user)

    profile = {
        'accounts': [{
            'domain': text_type('facebook.com'),
            'userid': text_type('2343')
        }],
        'displayName':
        text_type('teddy'),
        'preferredUsername':
        text_type('teddy'),
        'emails': [{
            'value': user.email
        }],
        'name':
        text_type('ted')
    }
    credentials = {'oauthAccessToken': '7897048593434'}
    provider_name = text_type('facebook')
    provider_type = text_type('facebook')
    user = None
    request = testing.DummyRequest()
    request.user = user
    request.registry = social_config.registry
    request.remote_addr = text_type('127.0.0.123')
    request.context = AuthenticationComplete(profile, credentials,
                                             provider_name, provider_type)

    request.login_perform = MagicMock(name='login_perform')
    request.login_perform.return_value = {'status': True}
    view = SocialLoginViews(request)
    out = view()
    assert out == {'status': True}
Exemple #29
0
    def post(self):
        """Validate and possibly accept new email."""
        user = self.request.matchdict.get('user')

        password = self.request.POST.get('password', None)
        password_confirm = self.request.POST.get('confirm_password', None)
        if password == password_confirm:

            try:
                self.request.registry.notify(BeforeReset(self.request, user))
                validate_passsword(self.request, password, user)

                user.reset_key = None
                try:
                    pyramid_basemodel.Session.query(
                        AuthenticationProvider).filter(
                            AuthenticationProvider.user_id == user.id,
                            AuthenticationProvider.provider == text_type(
                                'email')).one()
                except NoResultFound:
                    user.providers.append(
                        AuthenticationProvider(provider=text_type('email'),
                                               provider_id=user.id))

                pyramid_basemodel.Session.flush()
            except (ValidateError, AttributeError) as e:
                return {
                    'status': False,
                    'msg': text_type(e),
                    'csrf_token': self.request.session.get_csrf_token()
                }

            try:
                self.request.registry.notify(AfterReset(self.request, user))
            except HTTPRedirection as redirect:
                return redirect
        else:
            return {
                'status':
                False,
                'msg':
                self.request._('password-mismatch',
                               default='Password doesn\'t match',
                               domain='pyramid_fullauth'),
                'csrf_token':
                self.request.session.get_csrf_token()
            }

        return self.get()
    def password_validator(self, key, password):
        '''
            Password validator keeps new password hashed.
            Rises Value error on empty password

            :param User user: object instance that triggered event
            :param str password: new password
            :param str oldvalue: old password value
            :param initiatior: the attribute implementation object which initiated this event.
            :returns: hashed and salted password
            :rtype: str
            :raises: pyramid_fullauth.exceptions.EmptyError

            .. note::

                If you using this Mixin on your own User object, don't forget to add a listener as well, like that:

                .. code-block:: python

                    from sqlalchemy.event import listen

                    listen(User.password, 'set', User.password_listener, retval=True)

            .. note::

                For more information on Attribute Events in sqlalchemy see:

                :meth:`sqlalchemy.orm.events.AttributeEvents.set`

        '''

        if not password:
            raise EmptyError('password-empty')

        # reading default hash_algorithm
        hash_algorithm = self.__class__._hash_algorithm.property.columns[0].default.arg

        # getting currently used hash method
        hash_method = getattr(hashlib, hash_algorithm)

        # generating salt
        salt = hash_method()
        salt.update(os.urandom(60))
        salt_value = salt.hexdigest()

        # storing used hash algorithm
        self._hash_algorithm = hash_algorithm
        self._salt = text_type(salt_value)
        return text_type(self.__class__.hash_password(password, salt_value, hash_method))
def test_delete_admin(db_with_user):
    '''Admin user soft delete'''

    user = db_with_user.query(User).filter(User.email == text_type('*****@*****.**')).one()
    create_user(db_with_user, {'email': text_type('*****@*****.**'),
                               'address_ip': '127.0.0.1',
                               'password': '******',
                               'is_admin': True})

    user.is_admin = True
    db_with_user.commit()

    user.delete()

    assert user.deleted_at
def test_user_provider_id(db_with_user):

    user = db_with_user.query(User).filter(User.email == text_type('*****@*****.**')).one()
    # Provider does not exists yet
    assert not user.provider_id('email')

    provider = AuthenticationProvider()
    provider.provider = text_type('email')
    provider.provider_id = user.email
    user.providers.append(provider)
    db_with_user.commit()

    user = db_with_user.query(User).filter(User.email == text_type('*****@*****.**')).one()
    # Provider does not exists yet
    assert user.provider_id('email')
Exemple #33
0
def test_password_change(db_session, user, password):
    """User password change."""
    new_password = text_type(password)

    user = db_session.merge(user)
    old_password = user.password
    old_salt = user._salt
    user.password = new_password
    transaction.commit()

    user = db_session.query(User).filter(
        User.username == text_type('u1')).one()
    assert not user.password == old_password
    assert not user._salt == old_salt
    assert user.check_password(new_password)
def test_password_change(db_with_user, password):
    """User::password change"""

    new_password = text_type(password)

    user = db_with_user.query(User).filter(User.username == text_type("u1")).one()
    old_password = user.password
    old_salt = user._salt
    user.password = new_password
    db_with_user.commit()

    user = db_with_user.query(User).filter(User.username == text_type("u1")).one()
    assert not user.password == old_password
    assert not user._salt == old_salt
    assert user.check_password(new_password)
def test_introduce_username():
    """user gets introduced by username."""
    user = User()
    # 'User not saved should be represented by \'None\'')
    assert str(user) == 'None'
    user.id = 1
    # if id is set, user should be presented with it
    assert str(user) == '1'

    user.email = text_type('*****@*****.**')
    user.username = text_type('testowy')
    # To string should return username
    assert str(user) == 'testowy'
    # User should be represented by "<User (\'1\')>"
    assert user.__repr__() == "<User ('1')>"
Exemple #36
0
    def post(self):
        """Validate and possibly accept new email."""
        user = self.request.matchdict.get('user')

        password = self.request.POST.get('password', None)
        password_confirm = self.request.POST.get('confirm_password', None)
        if password == password_confirm:

            try:
                self.request.registry.notify(BeforeReset(self.request, user))
                validate_passsword(self.request, password, user)

                user.reset_key = None
                try:
                    pyramid_basemodel.Session.query(AuthenticationProvider).filter(
                        AuthenticationProvider.user_id == user.id,
                        AuthenticationProvider.provider == text_type('email')
                    ).one()
                except NoResultFound:
                    user.providers.append(
                        AuthenticationProvider(
                            provider=text_type('email'),
                            provider_id=user.id
                        )
                    )

                pyramid_basemodel.Session.flush()
            except (ValidateError, AttributeError) as ex:
                return {
                    'status': False,
                    'msg': text_type(ex),
                    'csrf_token': self.request.session.get_csrf_token()
                }

            try:
                self.request.registry.notify(AfterReset(self.request, user))
            except HTTPRedirection as redirect:
                return redirect
        else:
            return {
                'status': False,
                'msg': self.request._('password-mismatch',
                                      default='Password doesn\'t match',
                                      domain='pyramid_fullauth'),
                'csrf_token': self.request.session.get_csrf_token()
            }

        return self.get()
def test_afteremailchangeactivation(db_session, active_user,
                                    afteremailchange_app):
    """Confirm email change view with redirect from AfterEmailChangeActivation."""
    app = afteremailchange_app
    # login user
    authenticate(app)

    email = DEFAULT_USER['email']
    user = db_session.query(User).filter(User.email == email).one()

    new_email = text_type('*****@*****.**')
    user.set_new_email(new_email)
    transaction.commit()

    user = db_session.merge(user)
    res = app.get('/email/change/' + user.email_change_key)
    assert res.status_code == 302
    assert res.location == EVENT_URL.format(AfterEmailChangeActivation)

    with pytest.raises(NoResultFound):
        # there is no user with old email
        db_session.query(User).filter(User.email == email).one()

    user = db_session.query(User).filter(User.email == new_email).one()
    assert not user.email_change_key
Exemple #38
0
def rst_to_html(text):
    if not isinstance(text, text_type):
        text = text_type(text)

    sphinx, pub = get_sphinx()

    pub.set_source(text, None)

    try:
        pub.publish()
    except:
        log.warning('ReST to HTML error\n %s', text)
        return '<pre>%s</pre>' % text

    doctree = pub.document
    sphinx.env.filter_messages(doctree)
    for domain in sphinx.env.domains.values():
        domain.process_doc(sphinx.env, 'text', doctree)

    pub.writer.write(doctree, io.StringOutput(encoding='unicode'))
    pub.writer.assemble_parts()

    parts = pub.writer.parts
    return ''.join((parts['body_pre_docinfo'],
                    parts['docinfo'], parts['body']))
    def test_extract(self):
        from pyramid_amdjs.handlebars import extract_i18n

        f = NativeIO('<div>{{#i18n}}Test \n message{{/i18n}}</div>')

        d = extract_i18n(f, [], [], [])
        self.assertEqual(d[0], (5, None, text_type('Test \n message'), []))
Exemple #40
0
    def test_settings_group_multiple_validation(self):
        def validator1(fs, appstruct):
            raise ptah.form.Invalid('Error1', fs['node1'])

        def validator2(fs, appstruct):
            raise ptah.form.Invalid('Error2', fs['node2'])

        node1 = ptah.form.TextField('node1', default='test')

        node2 = ptah.form.TextField('node2', default='test')

        ptah.register_settings('group3',
                               node1,
                               node2,
                               validator=(validator1, validator2))

        self.init_ptah()

        group = ptah.get_settings('group3', self.registry)
        data, err = group.extract({
            'group3.node1': 'value',
            'group3.node2': 'value'
        })

        self.assertEqual(err.msg, {'group3': text_type(['Error1', 'Error2'])})
    def test_compile_existing(self):
        from pyramid_amdjs import handlebars

        self.cfg['amd.tmpl-cache'] = self.path
        prefix = os.path.split(self.path)[-1]

        f = os.path.join(self.path, 'template')
        with open(f, 'w') as fn:
            fn.write('<div>{{test}}</div>')

        time.sleep(0.01)

        f1 = os.path.join(self.path, 'test-%s-template' % prefix)
        with open(f1, 'w') as fn:
            fn.write('existing1')

        time.sleep(0.01)

        f2 = os.path.join(
            self.path, 'test-%s-template.js.%s' % (prefix, handlebars.VERSION))
        with open(f2, 'w') as fn:
            fn.write('existing2')

        tmpl = text_type(
            handlebars.compile_template('test', f, handlebars.compat.NODE_PATH,
                                        self.path)[0])

        self.assertEqual('existing2', tmpl)
    def test_compile_new(self):
        from pyramid_amdjs import handlebars

        self.cfg['amd.tmpl-cache'] = self.path
        prefix = os.path.split(self.path)[-1]

        f = os.path.join(self.path, 'template')
        with open(f, 'w') as fn:
            fn.write('<div>{{test}}</div>')

        tmpl = text_type(
            handlebars.compile_template('test', f, handlebars.compat.NODE_PATH,
                                        self.path)[0])

        self.assertTrue(
            os.path.isfile(os.path.join(self.path,
                                        'test-%s-template' % prefix)))
        self.assertTrue(
            os.path.isfile(
                os.path.join(
                    self.path,
                    'test-%s-template.js.%s' % (prefix, handlebars.VERSION))))

        self.assertIn('function (Handlebars,depth0,helpers,partials,data) {',
                      tmpl)
Exemple #43
0
def validate_passsword(request, password, user=None):
    """
    Validate password properly.

    .. note::

        If no user provided, password is just validated

    :param pyramid.request.Request request: request object
    :param str password: password to be set
    :param pyramid_fullauth.models.User user: user object

    :raises: pyramid_fullauth.exceptions.ValidateError
    """
    password_config = request.registry['config'].fullauth.register.password
    if not password:
        raise EmptyError(
            request._('Please enter your password', domain='pyramid_fullauth'))

    if password_config['length_min'] and\
            len(password) < password_config['length_min']:
        raise ShortPasswordError(
            request._('Password is too short', domain='pyramid_fullauth'))

    # here if password doesn't match
    if password_config['confirm']:
        confirm_password = request.POST.get('confirm_password', text_type(''))
        if password != confirm_password:
            raise PasswordConfirmMismatchError(
                request._('password-mismatch',
                          default='Passwords don\'t match',
                          domain='pyramid_fullauth'))

    if user:
        user.password = password
Exemple #44
0
class TestSqlaModuleBase(ptah.get_base()):
    __tablename__ = 'ptah_nodes'
    __table_args__ = {'extend_existing': True}
    __mapper_args__ = {'polymorphic_identity': 'node'}

    id = sqla.Column(sqla.Integer(), primary_key=True)
    name = sqla.Column(sqla.Unicode(), default=text_type('123'))
    def test_validate_email_ok(self):
        '''User::validate e-mail::ok'''

        user = User()
        email = text_type('*****@*****.**')
        user.email = email
        assert user.email == email
Exemple #46
0
def facebook_user(active_user, db_session):
    """Facebook user."""
    active_user = db_session.merge(active_user)
    active_user.providers.append(
        AuthenticationProvider(provider=text_type('facebook'), provider_id='1234'))
    transaction.commit()
    return db_session.merge(active_user)
def test_set_reset(db_with_user):
    """User::set_reset()"""

    user = db_with_user.query(User).filter(User.username == text_type("u1")).one()
    assert not user.reset_key
    user.set_reset()
    assert user.reset_key
Exemple #48
0
    def test_settings_group_multiple_validation(self):
        def validator1(fs, appstruct):
            raise ptah.form.Invalid('Error1', fs['node1'])

        def validator2(fs, appstruct):
            raise ptah.form.Invalid('Error2', fs['node2'])

        node1 = ptah.form.TextField(
            'node1',
            default = 'test')

        node2 = ptah.form.TextField(
            'node2',
            default = 'test')

        ptah.register_settings(
            'group3', node1, node2, validator=(validator1, validator2))

        self.init_ptah()

        group = ptah.get_settings('group3', self.registry)
        data, err = group.extract({
            'group3.node1': 'value',
            'group3.node2': 'value'})

        self.assertEqual(err.msg, {'group3': text_type(['Error1', 'Error2'])})
Exemple #49
0
def rst_to_html(text):
    if not isinstance(text, text_type):
        text = text_type(text)

    if not has_sphinx:  # pragma: no cover
        return '<pre>%s</pre>' % text if text else ''

    sphinx, pub = get_sphinx()

    pub.set_source(text, None)

    try:
        pub.publish()
    except:
        log.warning('ReST to HTML error\n %s', text)
        return '<pre>%s</pre>' % text

    doctree = pub.document
    sphinx.env.filter_messages(doctree)
    for domain in sphinx.env.domains.values():
        domain.process_doc(sphinx.env, 'text', doctree)

    pub.writer.write(doctree, io.StringOutput(encoding='unicode'))
    pub.writer.assemble_parts()

    parts = pub.writer.parts
    return ''.join(
        (parts['body_pre_docinfo'], parts['docinfo'], parts['body']))
Exemple #50
0
class CrowdGroup(ptah.get_base()):
    """Crowd group

    ``title``: Group title.

    ``description``: Group description.

    ``users``: Users list.

    """

    __tablename__ = 'ptahcrowd_groups'

    id = sqla.Column(sqla.Integer, primary_key=True)
    title = sqla.Column(sqla.Unicode(255))
    description = sqla.Column(sqla.UnicodeText, default=text_type(''),
                              info = {'missing': '', 'field_type': 'textarea',
                                      'default': '', 'required': False})

    _sql_get_id = ptah.QueryFreezer(
        lambda: ptah.get_session().query(CrowdGroup)\
            .filter(CrowdGroup.id==sqla.sql.bindparam('id')))

    @classmethod
    def get_byid(cls, id):
        return cls._sql_get_id.first(id=id)

    def __str__(self):
        return self.title
Exemple #51
0
    def __call__(self):
        """Login action."""
        if self.request.authenticated_userid:
            return self._redirect_authenticated_user()

        email = self.request.POST.get('email', '')
        password = self.request.POST.get('password', '')
        try:
            user = pyramid_basemodel.Session.query(User).filter(
                User.email == email).one()
        except NoResultFound:
            self.request.registry.notify(BeforeLogIn(self.request, None))

            self.response['msg'] = self.request._('Wrong e-mail or password.',
                                                  domain='pyramid_fullauth')
            return self.response

        try:
            self.request.registry.notify(BeforeLogIn(self.request, user))
        except AttributeError as e:
            self.response['msg'] = text_type(e)
            return self.response

        if user.check_password(password):

            login_kwargs = {'remember_me': self.request.POST.get('remember')}
            try:
                # if remember in POST set cookie timeout to one month
                self.request.registry.notify(AfterLogIn(self.request, user))
            except AttributeError as e:
                self.response['msg'] = text_type(e)
                return self.response
            except HTTPRedirection as redirect:
                login_kwargs['location'] = redirect.location

            redirect = self.request.login_perform(user, **login_kwargs)
            if self.request.is_xhr:
                self.response['status'] = True
                del self.response['msg']
                self.response['after'] = redirect.location
                return self.response
            else:
                return redirect
        else:
            self.response['msg'] = self.request._('Wrong e-mail or password.',
                                                  domain='pyramid_fullauth')
            return self.response
Exemple #52
0
    def auditstream_sse(self):
        """Returns an event stream suitable for driving an HTML5 EventSource.
           The event stream will contain auditing events.

           Obtain events for the context of the view only::

            var source = new EventSource(
               "${request.sdiapi.mgmt_path(context, 'auditstream-sse')}");
           
           Obtain events for a single OID unrelated to the context::

            var source = new EventSource(
               "${request.sdiapi.mgmt_path(context, 'auditstream-sse', _query={'oid':'12345'})}");

           Obtain events for a set of OIDs::

            var source = new EventSource(
               "${request.sdiapi.mgmt_path(context, 'auditstream-sse', _query={'oid':['12345', '56789']})}");

           Obtain all events for all oids::

            var source = new EventSource(
               "${request.sdiapi.mgmt_path(context, 'auditstream-sse', _query={'all':'1'})}");
           
           The executing user will need to possess the ``sdi.view-auditstream``
           permission against the context on which the view is invoked.
        """
        request = self.request
        response = request.response
        response.content_type = 'text/event-stream'
        last_event_id = request.headers.get('Last-Event-Id')
        scribe = self.AuditScribe(self.context)
        if not last_event_id:
            # first call, set a baseline event id
            gen, idx = scribe.latest_id()
            msg = compose_message('%s-%s' % (gen, idx))
            response.text = msg
            self.logger.debug('New SSE connection on %s, returning %s' %
                              (request.url, msg))
            return response
        else:
            if request.GET.get('all'):
                oids = ()
            elif request.GET.get('oid'):
                oids = map(int, request.GET.getall('oid'))
            else:
                oids = [get_oid(self.context)]
            _gen, _idx = map(int, last_event_id.split('-', 1))
            events = scribe.newer(_gen, _idx, oids=oids)
            msg = text_type('')
            for gen, idx, event in events:
                event_id = '%s-%s' % (gen, idx)
                message = compose_message(event_id, event.name, event.payload)
                msg += message
            self.logger.debug(
                'SSE connection on %s with id %s-%s, returning %s' %
                (request.url, _gen, _idx, msg))
            response.text = msg
            return response
Exemple #53
0
def _generate_random_string(length=12):
    """Generate a random ascii string of the requested length."""
    msg = hashlib.sha256()
    word = ''
    for _ in range(length):
        word += random.choice(string.ascii_letters)
    msg.update(word.encode('ascii'))
    return text_type(msg.hexdigest()[:length])
def test_reset_email_not_exists(user, db_session, default_app):
    """Reset password request with wrong email (not in database)."""
    user = db_session.merge(user)

    res = default_app.get('/password/reset')
    res.form['email'] = text_type('*****@*****.**')
    res = res.form.submit()
    assert 'Error! User does not exists' in res
Exemple #55
0
 def __unicode__(self):
     """Unicode cast rules."""
     if self.username:
         return self.username
     elif self.email:
         return self.email.split('@')[0] + '@...'
     else:
         return text_type(self.id)
Exemple #56
0
def before_language_insert(mapper, connection, language):
    """Set name and native_name before creation."""
    # Check language code
    try:
        lang_data = pycountry.languages.get(iso639_1_code=language.language_code)

    except KeyError:
        # Language code not recognized, set defaults
        language.name = text_type('UNKNOWN')
        language.native_name = text_type('UNKNOWN')
        return

    # Set name and native_name
    language.name = text_type(lang_data.name)

    if language.language_code == text_type('en'):
        # English does not have a translation file
        language.native_name = text_type(lang_data.name)

    else:
        lang_locale = gettext.translation(
            'iso639_3',
            pycountry.LOCALES_DIR,
            languages=[language.language_code]
        )
        l = lang_locale.gettext

        if PY3:
            language.native_name = text_type(l(lang_data.name))

        else:
            language.native_name = text_type(l(lang_data.name), 'utf-8')
Exemple #57
0
 def delete_view(self):
     if not hasattr(self.context, 'obj'):
         raise HTTPNotFound
     self.context.dbsession.delete(self.context.obj)
     self.commit()
     self.flash_message(
         _ps("You have removed object of ${name}",
             mapping={'name': escape(text_type(self.context.obj) or '')}))
     return self.list_view_response()
Exemple #58
0
def test_existing_email(db_session, active_user, default_app):
    """Try to change email to existing one email."""
    # add other user
    existing_email = text_type("*****@*****.**")
    db_session.add(
        User(email=existing_email,
             password=text_type("somepassword"),
             address_ip=DEFAULT_USER['address_ip']))
    transaction.commit()
    # login user
    authenticate(default_app)

    # submit request!
    res = default_app.get('/email/change')
    form = res.form
    form['email'] = existing_email
    res = form.submit()
    assert 'Error! User with this email exists' in res
Exemple #59
0
def date_formatter(request, value, format='medium', locale_name=None):
    """Date formatter
    """
    if not isinstance(value, datetime) and not isinstance(value, date):
        return value

    if not locale_name:
        locale_name = request.locale_name

    return text_type(format_date(value, format, locale_name))