def post(self): """Process registration request.""" response = { 'status': False, 'msg': self.request._('You have an error in your registration form', domain='pyramid_fullauth'), 'csrf_token': self.request.session.get_csrf_token(), 'errors': {}, } user = User() user.address_ip = self.request.remote_addr response = self._fillin_user(response, user) if not response['errors']: response['status'] = True response['msg'] = self.request._( 'You have successfully registered', domain='pyramid_fullauth') try: self.request.registry.notify(AfterRegister(self.request, user, response)) except HTTPRedirection as redirect: return redirect return response
def post(self): """Process registration request.""" response = { 'status': False, 'msg': self.request._('You have an error in your registration form', domain='pyramid_fullauth'), 'csrf_token': self.request.session.get_csrf_token(), 'errors': {}, } user = User() user.address_ip = self.request.remote_addr response = self._fillin_user(response, user) if not response['errors']: response['status'] = True response['msg'] = self.request._( 'You have successfully registered', domain='pyramid_fullauth') try: self.request.registry.notify( AfterRegister(self.request, user, response)) except HTTPRedirection as redirect: return redirect return response
def _register_user(self): """Actually register new user in the system based on context values.""" context = self.request.context email = self._email_from_context(context) try: user = pyramid_basemodel.Session.query(User).filter(User.email == email).one() # If we are here that means that in the DB exists user with the same email but without the provider # then we connect social account to this user if not self.set_provider( user, context.provider_name, context.profile['accounts'][0]['userid'] ): # authenticating user with different social account than assigned, # recogniced by same email address used logger.debug('''Authenticated {user.id} connected to {context.provider_name} id {connected_id}, with {userid}'''.format( user=user, context=context, connected_id=user.provider_id(context.provider_name), userid=context.profile['accounts'][0]['userid'])) pyramid_basemodel.Session.flush() except NoResultFound: length_min = self.config.register.password.length_min user = User( email=email, password=tools.password_generator(length_min), address_ip=self.request.remote_addr ) self.request.registry.notify(BeforeSocialRegister(self.request, user, context.profile)) self.set_provider(user, context.provider_name, context.profile['accounts'][0]['userid']) pyramid_basemodel.Session.add(user) pyramid_basemodel.Session.flush() user.is_active = True return user
def _register_user(self): """Actually register new user in the system based on context values.""" context = self.request.context email = self._email_from_context(context) try: user = pyramid_basemodel.Session.query(User).filter( User.email == email).one() # If we are here that means that in the DB exists user with the same email but without the provider # then we connect social account to this user if not self.set_provider(user, context.provider_name, context.profile['accounts'][0]['userid']): # authenticating user with different social account than assigned, # recogniced by same email address used logger.debug('''Authenticated {user.id} connected to {context.provider_name} id {connected_id}, with {userid}'''.format( user=user, context=context, connected_id=user.provider_id(context.provider_name), userid=context.profile['accounts'][0]['userid'])) pyramid_basemodel.Session.flush() except NoResultFound: length_min = self.config.register.password.length_min user = User(email=email, password=tools.password_generator(length_min), address_ip=self.request.remote_addr) self.request.registry.notify( BeforeSocialRegister(self.request, user, context.profile)) self.set_provider(user, context.provider_name, context.profile['accounts'][0]['userid']) pyramid_basemodel.Session.add(user) pyramid_basemodel.Session.flush() user.is_active = True return user
def test_validate_email_ok(self): '''User::validate e-mail::ok''' user = User() email = text_type('*****@*****.**') user.email = email assert user.email == email
def test_logged_social_connect_used_account(social_config, facebook_user, db_session): """Try to connect facebook account to logged in user used by other user.""" # this user will be logged and trying to connect facebook's user account. fresh_user = User( email="*****@*****.**", password="******", address_ip="127.0.0.1", ) db_session.add(fresh_user) transaction.commit() user = db_session.merge(facebook_user) fresh_user = db_session.merge(fresh_user) # mock request profile = { "accounts": [{ "domain": "facebook.com", "userid": user.provider_id("facebook"), }], "displayName": "teddy", "preferredUsername": "******", "emails": [{ "value": "*****@*****.**" }], "name": "ted", } credentials = {"oauthAccessToken": "7897048593434"} provider_name = "facebook" provider_type = "facebook" request = testing.DummyRequest() request.user = fresh_user request.registry = social_config.registry request.remote_addr = "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} # call! view = SocialLoginViews(request) out = view() # status should be false assert out["status"] is False assert out[ "msg"] == "This ${provider} account is already connected with other account." transaction.begin() fresh_user = db_session.merge(fresh_user) assert fresh_user.provider_id("facebook") is None
def test_alreadyconnected(alreadyconnected_config, facebook_user, db_session): # pylint:disable=redefined-outer-name """ Try to connect facebook account to logged in user used by other users facebook account. Check redirect from SocialAccountAlreadyConnected. """ # this user will be logged and trying to connect facebook's user account. fresh_user = User( email="*****@*****.**", password="******", address_ip="127.0.0.1", ) db_session.add(fresh_user) transaction.commit() user = db_session.merge(facebook_user) fresh_user = db_session.merge(fresh_user) # mock request profile = { "accounts": [{ "domain": "facebook.com", "userid": user.provider_id("facebook"), }], "displayName": "teddy", "preferredUsername": "******", "emails": [{ "value": "*****@*****.**" }], "name": "ted", } credentials = {"oauthAccessToken": "7897048593434"} provider_name = "facebook" provider_type = "facebook" request = testing.DummyRequest() request.user = fresh_user request.registry = alreadyconnected_config.registry request.remote_addr = "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} # call! view = SocialLoginViews(request) out = view() assert out.location == EVENT_PATH.format(SocialAccountAlreadyConnected) transaction.begin() fresh_user = db_session.merge(fresh_user) assert fresh_user.provider_id("facebook") is None
def test_logged_social_connect_used_account(social_config, facebook_user, db_session): """Try to connect facebook account to logged in user used by other user.""" # this user will be logged and trying to connect facebook's user account. fresh_user = User(email='*****@*****.**', password='******', address_ip='127.0.0.1') db_session.add(fresh_user) transaction.commit() user = db_session.merge(facebook_user) fresh_user = db_session.merge(fresh_user) # mock request profile = { 'accounts': [{ 'domain': u'facebook.com', 'userid': user.provider_id('facebook') }], 'displayName': u'teddy', 'preferredUsername': u'teddy', 'emails': [{ 'value': u'*****@*****.**' }], 'name': u'ted' } credentials = {'oauthAccessToken': '7897048593434'} provider_name = u'facebook' provider_type = u'facebook' request = testing.DummyRequest() request.user = fresh_user request.registry = social_config.registry request.remote_addr = u'127.0.0.123' request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type) request._ = lambda msg, *args, **kwargs: msg request.login_perform = MagicMock(name='login_perform') request.login_perform.return_value = {'status': True} # call! view = SocialLoginViews(request) out = view() # status should be false assert out['status'] is False assert out[ 'msg'] == 'This ${provider} account is already connected with other account.' transaction.begin() fresh_user = db_session.merge(fresh_user) assert fresh_user.provider_id('facebook') is None
def test_set_new_email(): """ Test User.set_new_email method. setting new email should result in setting new_email field, and key used to activate the change. """ user = User() assert user.email_change_key is None assert user.new_email is None user.set_new_email(NEW_EMAIL) assert user.new_email == NEW_EMAIL assert user.email_change_key
def test_change_email(): """ Test User.change_email method. Calling it should copy new email set by set_new_email method into regular email field. """ user = User() assert not user.email user.set_new_email(NEW_EMAIL) user.change_email() assert not user.email_change_key assert user.email == NEW_EMAIL
def test_alreadyconnected(alreadyconnected_config, alreadyconnected_app, facebook_user, db_session): """Try to connect facebook account to logged in user used by other user check redirect from SocialAccountAlreadyConnected.""" # this user will be logged and trying to connect facebook's user account. fresh_user = User(email=text_type('*****@*****.**'), password=text_type('somepassword'), address_ip=text_type('127.0.0.1')) db_session.add(fresh_user) transaction.commit() user = db_session.merge(facebook_user) fresh_user = db_session.merge(fresh_user) # mock request profile = { 'accounts': [{ 'domain': text_type('facebook.com'), 'userid': user.provider_id('facebook') }], '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 = fresh_user request.registry = alreadyconnected_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} # call! view = SocialLoginViews(request) out = view() assert out.location == EVENT_PATH.format(SocialAccountAlreadyConnected) transaction.begin() fresh_user = db_session.merge(fresh_user) assert fresh_user.provider_id('facebook') is None
def test_logged_social_connect_used_account(social_config, facebook_user, db_session): """Try to connect facebook account to logged in user used by other user.""" # this user will be logged and trying to connect facebook's user account. fresh_user = User( email=text_type('*****@*****.**'), password=text_type('somepassword'), address_ip=text_type('127.0.0.1') ) db_session.add(fresh_user) transaction.commit() user = db_session.merge(facebook_user) fresh_user = db_session.merge(fresh_user) # mock request profile = { 'accounts': [{'domain': text_type('facebook.com'), 'userid': user.provider_id('facebook')}], '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 = fresh_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} # call! view = SocialLoginViews(request) out = view() # status should be false assert out['status'] is False assert out['msg'] == 'This ${provider} account is already connected with other account.' transaction.begin() fresh_user = db_session.merge(fresh_user) assert fresh_user.provider_id(text_type('facebook')) is None
def user(db_session): """Default user.""" from pyramid_fullauth.models import User from tests.tools import DEFAULT_USER user = User(**DEFAULT_USER) db_session.add(user) transaction.commit() return user
def user(db_session): # pylint:disable=redefined-outer-name """Test user fixture.""" from pyramid_fullauth.models import User # pylint:disable=import-outside-toplevel from tests.tools import DEFAULT_USER # pylint:disable=import-outside-toplevel new_user = User(**DEFAULT_USER) db_session.add(new_user) transaction.commit() return new_user
def test_alreadyconnected(alreadyconnected_config, facebook_user, db_session): # pylint:disable=redefined-outer-name """ Try to connect facebook account to logged in user used by other users facebook account. Check redirect from SocialAccountAlreadyConnected. """ # this user will be logged and trying to connect facebook's user account. fresh_user = User( email=text_type('*****@*****.**'), password=text_type('somepassword'), address_ip=text_type('127.0.0.1') ) db_session.add(fresh_user) transaction.commit() user = db_session.merge(facebook_user) fresh_user = db_session.merge(fresh_user) # mock request profile = { 'accounts': [{'domain': text_type('facebook.com'), 'userid': user.provider_id('facebook')}], '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 = fresh_user request.registry = alreadyconnected_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} # call! view = SocialLoginViews(request) out = view() assert out.location == EVENT_PATH.format(SocialAccountAlreadyConnected) transaction.begin() fresh_user = db_session.merge(fresh_user) assert fresh_user.provider_id(text_type('facebook')) is None
def test_logged_social_connect_used_account(social_config, facebook_user, db_session): """Try to connect facebook account to logged in user used by other user.""" # this user will be logged and trying to connect facebook's user account. fresh_user = User( email=text_type("*****@*****.**"), password=text_type("somepassword"), address_ip=text_type("127.0.0.1") ) db_session.add(fresh_user) transaction.commit() user = db_session.merge(facebook_user) fresh_user = db_session.merge(fresh_user) # mock request profile = { "accounts": [{"domain": text_type("facebook.com"), "userid": user.provider_id("facebook")}], "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 = fresh_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} # call! view = SocialLoginViews(request) out = view() # status should be false assert out["status"] is False assert out["msg"] == "This ${provider} account is already connected with other account." transaction.begin() fresh_user = db_session.merge(fresh_user) assert fresh_user.provider_id("facebook") is None
def test_delete_admin(db_session, user): """Admin user soft delete behaviour - more than one admins present.""" user = db_session.merge(user) user2 = User(email=text_type('*****@*****.**'), address_ip='127.0.0.1', password='******', is_admin=True) db_session.add(user2) user.is_admin = True transaction.commit() user = db_session.merge(user) user.delete() assert user.deleted_at
def post(self): """Process registration request.""" response = { "status": False, "msg": self.request._("You have an error in your registration form", domain="pyramid_fullauth"), "csrf_token": self.request.session.get_csrf_token(), "errors": {}, } user = User() user.address_ip = self.request.remote_addr response = self._fillin_user(response, user) if not response["errors"]: response["status"] = True response["msg"] = self.request._("You have successfully registered", domain="pyramid_fullauth") try: self.request.registry.notify(AfterRegister(self.request, user, response)) except HTTPRedirection as redirect: return redirect return response
def test_delete_admin(db_session, user): """Admin user soft delete behaviour - more than one admins present.""" user = db_session.merge(user) user2 = User( email="*****@*****.**", address_ip="127.0.0.1", password="******", is_admin=True, ) db_session.add(user2) user.is_admin = True transaction.commit() user = db_session.merge(user) user.delete() assert user.deleted_at
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
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 = "*****@*****.**" user.username = "******" # To string should return username assert str(user) == "testowy" # User should be represented by "<User (\'1\')>" assert user.__repr__() == "<User ('1')>"
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')>"
def test_existing_email(db_session, default_app): """Try to change email to existing one email.""" # add other user existing_email = "*****@*****.**" db_session.add( User( email=existing_email, password="******", 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
def register_social(self): ''' Action provides social authorization functionality. When authorization with facebook or twitter is done successfully action tries to find existing user in database, if it exists - login this user, otherwise creates new user. ''' def set_provider(user, provider_name, user_provider_id): ''' Method sets the provider authentication method for user. ''' if user.id: try: provider_auth = Session.query( AuthenticationProvider).filter(AuthenticationProvider.user_id == user.id, AuthenticationProvider.provider == provider_name).one() if provider_auth.provider_id != user_provider_id: return False return True except NoResultFound: pass provider_auth = AuthenticationProvider() provider_auth.provider = provider_name provider_auth.provider_id = user_provider_id user.providers.append(provider_auth) return True context = self.request.context response_values = {'status': False, 'csrf_token': self.request.session.get_csrf_token()} user = self.request.user if user: # when user is logged in already, just connect social account to # this app account try: if set_provider(user, context.provider_name, context.profile['accounts'][0]['userid']): Session.flush() else: response_values['msg'] = 'Your account is already connected to other {provider} account.'.format( provider=context.provider_name) return response_values except IntegrityError: response_values['msg'] = 'This {provider} account is already connected with other account.'.format( provider=context.provider_name) try: self.request.registry.notify(SocialAccountAlreadyConnected( self.request, user, context.profile, response_values)) except HTTPFound as redirect: # it's a redirect, let's follow it! return redirect return response_values else: # getting verified email from provider if 'verifiedEmail' in context.profile: email = context.profile['verifiedEmail'] # getting first of the emails provided by social login provider elif 'emails' in context.profile and context.profile['emails'] and 'value' in context.profile['emails'][0]: email = context.profile['emails'][0]['value'] # generating some random email address based on social userid and provider domain else: email = u'{0}@{1}'.format(context.profile['accounts'][ 0]['userid'], context.profile['accounts'][0]['domain']) try: user = Session.query( User).join(AuthenticationProvider).filter(AuthenticationProvider.provider == context.provider_name, AuthenticationProvider.provider_id == context.profile['accounts'][0]['userid']).one() except NoResultFound: user = None # If the user for the provider was not found then check if in the DB exists user with the same email if not user: try: user = Session.query(User).filter(User.email == email).one() # If we are here that means that in the DB exists user with the same email but without the provider # then we connect social account to this user set_provider(user, context.provider_name, context.profile['accounts'][0]['userid']) Session.flush() except NoResultFound: length_min = self.request.config.fullauth.register.password.length_min user = User(email=email, password=tools.password_generator(length_min), address_ip=self.request.remote_addr) self.request.registry.notify(BeforeSocialRegister(self.request, user, context.profile)) set_provider(user, context.provider_name, context.profile['accounts'][0]['userid']) Session.add(user) Session.flush() user.is_active = True try: self.request.registry.notify(AfterSocialRegister( self.request, user, context.profile, response_values)) except HTTPFound as redirect: # it's a redirect, let's follow it! return redirect # if we're here, user exists try: self.request.registry.notify(AfterSocialLogIn(self.request, user, context.profile)) except HTTPFound as redirect: # it's a redirect, let's follow it! return self.request.login_perform(user, location=redirect.location) else: return self.request.login_perform(user)
def test_introduce_email(): """User gets introduced by e-mail only.""" user = User() user.email = "*****@*****.**" # To string should return concatenated email assert str(user) == "test@..."
def test_introduce_email(): """user gets introduced by e-mail only.""" user = User() user.email = text_type('*****@*****.**') # To string should return concatenated email assert str(user) == 'test@...'
def test_validate_email_bad(self): '''User::validate e-mail::bad''' user = User() with pytest.raises(EmailValidationError): user.email = text_type('bad-mail')
def test_email_empty(self): '''Test reaction of email validator for empty email''' user = User() with pytest.raises(EmptyError): user.email = text_type('')
def test_is_active_error(): '''Is active can only be modified on object in session!''' with pytest.raises(AttributeError): user = User() user.is_active = True
def register_POST(self): ''' Process POST register request ''' invalid_fields = {} response_values = { 'status': False, 'msg': self.request._('You have an error in your registration form', domain='pyramid_fullauth'), 'csrf_token': self.request.session.get_csrf_token()} response_values['errors'] = invalid_fields email = self.request.POST.get('email', u'') # here if e-mail is already in database try: Session.query(User).filter(User.email == email).one() invalid_fields['email'] = self.request._('User with given e-mail already exists!', domain='pyramid_fullauth') except NoResultFound: pass try: user = User() try: user.email = email except ValidateError as e: # do not overwrite existing error if not 'email' in invalid_fields: invalid_fields['email'] = str(e) user.address_ip = self.request.remote_addr if self.request.config.fullauth.register.password.require: try: tools.validate_passsword(self.request, self.request.POST.get('password', u''), user) except ValidateError as e: invalid_fields['password'] = e.message else: user.password = tools.password_generator( self.request.config.fullauth.register.password.length_min) self.request.registry.notify(BeforeRegister(self.request, user, invalid_fields)) if not invalid_fields: Session.add(user) Session.flush() # lets add AuthenticationProvider as email! user.providers.append( AuthenticationProvider(provider=u'email', provider_id=user.id)) else: return response_values except AttributeError as e: invalid_fields['msg'] = str(e) return response_values response_values['status'] = True response_values['msg'] = self.request._('You have successfully registered', domain='pyramid_fullauth') try: self.request.registry.notify(AfterRegister(self.request, user, response_values)) except HTTPFound as redirect: return redirect return response_values
def test_is_active_error(): """is_active can only be modified on object in session.""" with pytest.raises(AttributeError): user = User() user.is_active = True