Example #1
0
    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)
Example #2
0
    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)
Example #3
0
    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
Example #4
0
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 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')
Example #6
0
    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
Example #7
0
    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)
Example #8
0
    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)
Example #9
0
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
Example #10
0
    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
Example #11
0
    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
Example #12
0
 def provider_module(self):
     from inbox.auth import handler_from_provider
     return handler_from_provider(self.provider)
Example #13
0
File: oauth.py Project: dlitz/inbox
 def provider_module(self):
     from inbox.auth import handler_from_provider
     return handler_from_provider(self.provider)
Example #14
0
 def auth_handler(self):
     from inbox.auth import handler_from_provider
     return handler_from_provider(self.provider)
Example #15
0
 def auth_handler(self):
     from inbox.auth import handler_from_provider
     return handler_from_provider(self.provider)