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_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_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_is_active_error(): """is_active can only be modified on object in session.""" with pytest.raises(AttributeError): user = User() user.is_active = True