def _new_connection(self): # Ensure that connections are initialized serially, so as not to use # many db sessions on startup. with self._new_conn_lock as _, session_scope() as db_session: from inbox.auth import handler_from_provider account = db_session.query(ImapAccount).get(self.account_id) auth_handler = handler_from_provider(account.provider) try: conn = auth_handler.connect_account(account) except ValidationError: logger.error("Error obtaining access token", account_id=self.account_id) account.sync_state = 'invalid' db_session.add(account) db_session.commit() return None except ConnectionError: logger.error("Error connecting", account_id=self.account_id) account.sync_state = 'connerror' db_session.add(account) db_session.commit() return None return new_crispin(self.account_id, self.email_address, self.provider_name, conn, self.readonly)
def _new_connection(self): from inbox.auth import handler_from_provider # Ensure that connections are initialized serially, so as not to use # many db sessions on startup. with self._new_conn_lock as _: auth_handler = handler_from_provider(self.provider_name) for retry_count in range(MAX_TRANSIENT_ERRORS): try: conn = auth_handler.connect_account( self.email_address, self.credential, self.imap_endpoint, self.account_id) # If we can connect the account, then we can set the sate # to 'running' if it wasn't already if self.sync_state != 'running': with session_scope() as db_session: query = db_session.query(ImapAccount) account = query.get(self.account_id) self.sync_state = account.sync_state = 'running' return self.client_cls(self.account_id, self.provider_info, self.email_address, conn, readonly=self.readonly) except ConnectionError, e: if isinstance(e, TransientConnectionError): return None else: logger.error('Error connecting', account_id=self.account_id) with session_scope() as db_session: query = db_session.query(ImapAccount) account = query.get(self.account_id) account.sync_state = 'connerror' account.update_sync_error(str(e)) return None except ValidationError, e: # If we failed to validate, but the account is oauth2, we # may just need to refresh the access token. Try this one # time. if (self.provider_info['auth'] == 'oauth2' and retry_count == 0): with session_scope() as db_session: query = db_session.query(ImapAccount) account = query.get(self.account_id) self.credential = token_manager.get_token( account, force_refresh=True) else: logger.error('Error validating', account_id=self.account_id) with session_scope() as db_session: query = db_session.query(ImapAccount) account = query.get(self.account_id) account.sync_state = 'invalid' account.update_sync_error(str(e)) raise
def test_auth_handler_dispatch(): assert isinstance(handler_from_provider('custom'), GenericAuthHandler) assert isinstance(handler_from_provider('fastmail'), GenericAuthHandler) assert isinstance(handler_from_provider('aol'), GenericAuthHandler) assert isinstance(handler_from_provider('yahoo'), GenericAuthHandler) assert isinstance(handler_from_provider('gmail'), GmailAuthHandler) assert isinstance(handler_from_provider('outlook'), OutlookAuthHandler) with pytest.raises(NotSupportedError): handler_from_provider('NOTAREALMAILPROVIDER')
def _new_connection(self): from inbox.auth import handler_from_provider # Ensure that connections are initialized serially, so as not to use # many db sessions on startup. with self._new_conn_lock as _: auth_handler = handler_from_provider(self.provider_name) for retry_count in range(MAX_TRANSIENT_ERRORS): try: conn = auth_handler.connect_account(self.email_address, self.credential, self.imap_endpoint, self.account_id) # If we can connect the account, then we can set the sate # to 'running' if it wasn't already if self.sync_state != 'running': with session_scope() as db_session: query = db_session.query(ImapAccount) account = query.get(self.account_id) self.sync_state = account.sync_state = 'running' return self.client_cls(self.account_id, self.provider_info, self.email_address, conn, readonly=self.readonly) except ConnectionError, e: if isinstance(e, TransientConnectionError): return None else: logger.error('Error connecting', account_id=self.account_id) with session_scope() as db_session: query = db_session.query(ImapAccount) account = query.get(self.account_id) account.sync_state = 'connerror' account.update_sync_error(str(e)) return None except ValidationError, e: # If we failed to validate, but the account is oauth2, we # may just need to refresh the access token. Try this one # time. if (self.provider_info['auth'] == 'oauth2' and retry_count == 0): with session_scope() as db_session: query = db_session.query(ImapAccount) account = query.get(self.account_id) self.credential = token_manager.get_token( account, force_refresh=True) else: logger.error('Error validating', account_id=self.account_id) with session_scope() as db_session: query = db_session.query(ImapAccount) account = query.get(self.account_id) account.sync_state = 'invalid' account.update_sync_error(str(e)) raise
def _new_connection(self): with session_scope() as db_session: from inbox.auth import handler_from_provider account = db_session.query(ImapAccount).get(self.account_id) auth_handler = handler_from_provider(account.provider) conn = auth_handler.verify_account(account) return new_crispin(self.account_id, self.provider, conn, self.readonly)
def _new_connection(self): # Ensure that connections are initialized serially, so as not to use # many db sessions on startup. with self._new_conn_lock as _, session_scope() as db_session: from inbox.auth import handler_from_provider account = db_session.query(ImapAccount).get(self.account_id) auth_handler = handler_from_provider(account.provider) # FIXME @karim: This code is slightly complex - we may # get transient errors (TransientConnectionError) when # connecting. We want to retry once before giving up # but we also need to handle other more serious errors. # The 'solution' is to wrap the code in a loop and continue # only on a TransientConnectionError. for i in range(2): try: conn = auth_handler.connect_account(account) except TransientConnectionError: gevent.sleep(random.uniform(1, 10)) if i < 2: continue else: # Retry only once. logger.error("Error connecting", account_id=self.account_id) account.sync_state = 'connerror' db_session.add(account) db_session.commit() return None except ValidationError: logger.error("Error obtaining access token", account_id=self.account_id) account.sync_state = 'invalid' db_session.add(account) db_session.commit() return None except ConnectionError: logger.error("Error connecting", account_id=self.account_id) account.sync_state = 'connerror' db_session.add(account) db_session.commit() return None return new_crispin(self.account_id, self.email_address, self.provider_name, conn, self.readonly)
def create_account(db_session, email, password): provider = provider_from_address(email) auth_handler = handler_from_provider(provider) # Special-case Gmail and Outlook, because we need to provide an oauth token # and not merely a password. response = {'email': email} if provider == 'gmail': code = google_auth(email, password) response = auth_handler._get_authenticated_user(code) elif provider == 'outlook': code = outlook_auth(email, password) response = auth_handler._get_authenticated_user(code) else: response = {"email": email, "password": password} account = auth_handler.create_account(db_session, email, response) auth_handler.verify_account(account) db_session.add(account) db_session.commit() return account
def _new_connection(self): from inbox.auth import handler_from_provider num_transients = 0 max_transient_retries = 2 # Ensure that connections are initialized serially, so as not to use # many db sessions on startup. with self._new_conn_lock as _, session_scope() as db_session: account = db_session.query(ImapAccount).get(self.account_id) auth_handler = handler_from_provider(account.provider) while True: try: conn = auth_handler.connect_account(account) except ConnectionError, e: if isinstance(e, TransientConnectionError) and \ num_transients < max_transient_retries: num_transients += 1 gevent.sleep(random.uniform(1, 10)) continue else: logger.error('Error connecting', account_id=self.account_id) account.sync_state = 'connerror' db_session.add(account) db_session.commit() return None except ValidationError: logger.error('Error obtaining access token', account_id=self.account_id) account.sync_state = 'invalid' db_session.add(account) db_session.commit() return None break
def provider_module(self): from inbox.auth import handler_from_provider return handler_from_provider(self.provider)
def auth_handler(self): from inbox.auth import handler_from_provider return handler_from_provider(self.provider)