def _create_account(settings, ssl): email = settings['settings']['email'] handler = GenericAuthHandler(settings['provider']) credentials = copy.deepcopy(settings) credentials['settings']['ssl_required'] = ssl account = handler.create_account(email, credentials['settings']) return account
def modify_account(namespace_public_id): """ Modify an existing account This stops syncing an account until it is explicitly resumed. """ data = request.get_json(force=True) with global_session_scope() as db_session: namespace = (db_session.query(Namespace).filter( Namespace.public_id == namespace_public_id).one()) account = namespace.account if isinstance(account, GenericAccount): auth_handler = GenericAuthHandler() account_data = _get_account_data_for_generic_account(data) elif isinstance(account, GmailAccount): auth_handler = GoogleAuthHandler() account_data = _get_account_data_for_google_account(data) elif isinstance(account, OutlookAccount): auth_handler = MicrosoftAuthHandler() account_data = _get_account_data_for_microsoft_account(data) else: raise ValueError("Account type not supported.") account = auth_handler.update_account(account, account_data) db_session.add(account) db_session.commit() encoder = APIEncoder() return encoder.jsonify(account.namespace)
def test_successful_reauth_resets_sync_state(db): settings = { 'provider': 'yahoo', 'settings': { 'name': 'Y.Y!', 'locale': 'fr', 'email': '*****@*****.**', 'password': '******'} } email = settings['settings']['email'] handler = GenericAuthHandler(settings['provider']) account = handler.create_account(email, settings['settings']) assert handler.verify_account(account) is True # Brand new accounts have `sync_state`=None. assert account.sync_state is None db.session.add(account) db.session.commit() # Pretend account sync starts, and subsequently the password changes, # causing the account to be in `sync_state`='invalid'. account.mark_invalid() db.session.commit() assert account.sync_state == 'invalid' # Verify the `sync_state` is reset to 'running' on a successful "re-auth". account = handler.update_account(account, settings['settings']) assert handler.verify_account(account) is True assert account.sync_state == 'running' db.session.add(account) db.session.commit()
def test_update_account_when_no_server_provided(db): email = settings['settings']['email'] imap_host = settings['settings']['imap_server_host'] imap_port = settings['settings']['imap_server_port'] smtp_host = settings['settings']['smtp_server_host'] smtp_port = settings['settings']['smtp_server_port'] handler = GenericAuthHandler(settings['provider']) account = handler.create_account(email, settings['settings']) # On successful auth, the account's imap_server is stored. db.session.add(account) db.session.commit() id_ = account.id db.session.commit() # Valid updates: # A future authentication does not include the `imap_server_host` either. db.session.expire(account) account = db.session.query(Account).get(id_) updated_settings = copy.deepcopy(settings) del updated_settings['settings']['imap_server_host'] del updated_settings['settings']['smtp_server_host'] account = handler.update_account(account, updated_settings['settings']) db.session.add(account) db.session.commit() account = db.session.query(Account).get(id_) acc_imap_host, acc_imap_port = account.imap_endpoint assert acc_imap_host == imap_host assert acc_imap_port == imap_port acc_smtp_host, acc_smtp_port = account.smtp_endpoint assert acc_smtp_host == smtp_host assert acc_smtp_port == smtp_port # A future authentication has the `imap_server_host='' # and smtp_server_host=''`. # This is what happens in the legacy auth flow, since # Proposal.imap_server_host and smtp_server_host will be set to u'' # if not provided. db.session.expire(account) account = db.session.query(Account).get(id_) updated_settings['settings']['imap_server_host'] = u'' updated_settings['settings']['smtp_server_host'] = u'' account = handler.update_account(account, updated_settings['settings']) db.session.add(account) db.session.commit() account = db.session.query(Account).get(id_) acc_imap_host, acc_imap_port = account.imap_endpoint assert acc_imap_host == imap_host assert acc_imap_port == imap_port acc_smtp_host, acc_smtp_port = account.smtp_endpoint assert acc_smtp_host == smtp_host assert acc_smtp_port == smtp_port
def generic_account(db): from inbox.auth.generic import GenericAuthHandler handler = GenericAuthHandler(provider_name='generic') acc = handler.create_account(db.session, 'user@generic_email.com', {'email': '*****@*****.**', 'password': '******'}) db.session.add(acc) db.session.commit() return acc
def generic_account(db): from inbox.auth.generic import GenericAuthHandler handler = GenericAuthHandler(provider_name='generic') acc = handler.create_account(db.session, 'user@generic_email.com', { 'email': '*****@*****.**', 'password': '******' }) db.session.add(acc) db.session.commit() return acc
def test_auth(creds): handler = GenericAuthHandler(creds['provider']) email = creds['settings']['email'] account = handler.create_account(email, creds['settings']) # Test that the account was successfully created by the handler. if 'smtp_password' in creds['settings']: assert account.imap_password == creds['settings']['imap_password'] assert account.smtp_password == creds['settings']['smtp_password'] else: assert account.imap_password == creds['settings']['password'] assert account.smtp_password == creds['settings']['password'] # Test that the account is valid. assert handler.verify_account(account) is True # Test that the password can be updated... bad_creds = {'email': creds['settings']['email'], 'imap_password': '******', 'imap_server_host': creds['settings'].get('imap_server_host'), 'imap_server_port': 993, 'smtp_server_host': creds['settings'].get('smtp_server_host'), 'smtp_server_port': 587 } handler.update_account(account, bad_creds) assert account.imap_password == 'bad_password' # ...but logging in again won't work. with pytest.raises(ValidationError): handler.verify_account(account)
def local_smtp_account(db): from inbox.auth.generic import GenericAuthHandler handler = GenericAuthHandler(provider_name='custom') acc = handler.create_account(db.session, '*****@*****.**', {'email': '*****@*****.**', 'password': '******', 'imap_server_host': 'imap-test.nylas.com', 'imap_server_port': 143, 'smtp_server_host': SMTP_SERVER_HOST, 'smtp_server_port': SMTP_SERVER_PORT}) db.session.add(acc) db.session.commit() return acc
def yahoo_account(db): account = GenericAuthHandler('yahoo').create_account( TEST_YAHOO_EMAIL, {"email": TEST_YAHOO_EMAIL, "password": "******"}) db.session.add(account) db.session.commit() return account
def local_smtp_account(db): from inbox.auth.generic import GenericAuthHandler handler = GenericAuthHandler(provider_name='custom') acc = handler.create_account( db.session, '*****@*****.**', { 'email': '*****@*****.**', 'password': '******', 'imap_server_host': 'imap-test.nylas.com', 'imap_server_port': 143, 'smtp_server_host': SMTP_SERVER_HOST, 'smtp_server_port': SMTP_SERVER_PORT }) db.session.add(acc) db.session.commit() return acc
def test_update_account(db): handler = GenericAuthHandler() # Create an authenticated account account = handler.create_account(account_data) db.session.add(account) db.session.commit() id_ = account.id # A valid update updated_data = attr.evolve(account_data, imap_username="******") account = handler.update_account(account, updated_data) db.session.add(account) db.session.commit() account = db.session.query(Account).get(id_) assert account.imap_username == "*****@*****.**"
def test_auth(creds): handler = GenericAuthHandler(creds['provider']) email = creds['settings']['email'] account = handler.create_account(email, creds['settings']) # Test that the account was successfully created by the handler. if 'smtp_password' in creds['settings']: assert account.imap_password == creds['settings']['imap_password'] assert account.smtp_password == creds['settings']['smtp_password'] else: assert account.imap_password == creds['settings']['password'] assert account.smtp_password == creds['settings']['password'] # Test that the account is valid. assert handler.verify_account(account) is True # Test that the password can be updated... bad_creds = {'email': creds['settings']['email'], 'smtp_password': '******', 'imap_server_host': creds['settings'].get('imap_server_host'), 'imap_server_port': 993, 'smtp_server_host': creds['settings'].get('smtp_server_host'), 'smtp_server_port': 587 } handler.update_account(account, bad_creds) assert account.smtp_password == 'bad_password' # ...but logging in again won't work. with pytest.raises(UserRecoverableConfigError): handler.verify_account(account)
def test_create_account(db): email = settings['settings']['email'] imap_host = settings['settings']['imap_server_host'] imap_port = settings['settings']['imap_server_port'] smtp_host = settings['settings']['smtp_server_host'] smtp_port = settings['settings']['smtp_server_port'] handler = GenericAuthHandler(settings['provider']) # Create an authenticated account account = handler.create_account(email, settings['settings']) db.session.add(account) db.session.commit() # Verify its settings id_ = account.id account = db.session.query(Account).get(id_) assert account.imap_endpoint == (imap_host, imap_port) assert account.smtp_endpoint == (smtp_host, smtp_port)
def test_auth(settings): handler = GenericAuthHandler(settings['provider']) has_starttls = ('aol' in settings['settings']['imap_server_host']) if has_starttls: account = _create_account(settings, ssl=True) handler.verify_account(account) else: account = _create_account(settings, ssl=True) with pytest.raises(Exception): handler.verify_account(account) account = _create_account(settings, ssl=False) handler.verify_account(account)
def local_smtp_account(db): from inbox.auth.generic import GenericAccountData, GenericAuthHandler handler = GenericAuthHandler() acc = handler.create_account( GenericAccountData( email="*****@*****.**", imap_username="******", smtp_username="******", imap_password="******", smtp_password="******", imap_server_host="imap-test.nylas.com", imap_server_port=143, smtp_server_host=SMTP_SERVER_HOST, smtp_server_port=postel.SMTP_OVER_SSL_TEST_PORT, sync_email=True, )) db.session.add(acc) db.session.commit() return acc
def test_create_account(db): email = settings['settings']['email'] imap_host = settings['settings']['imap_server_host'] imap_port = settings['settings']['imap_server_port'] smtp_host = settings['settings']['smtp_server_host'] smtp_port = settings['settings']['smtp_server_port'] handler = GenericAuthHandler(settings['provider']) # Create an authenticated account account = handler.create_account(email, settings['settings']) db.session.add(account) db.session.commit() # Verify its settings id_ = account.id account = db.session.query(Account).get(id_) assert account.imap_endpoint == (imap_host, imap_port) assert account.smtp_endpoint == (smtp_host, smtp_port) # Ensure that the emailed events calendar was created assert account._emailed_events_calendar is not None assert account._emailed_events_calendar.name == 'Emailed events'
def test_create_account(db): handler = GenericAuthHandler() # Create an authenticated account account = handler.create_account(account_data) db.session.add(account) db.session.commit() # Verify its settings id_ = account.id account = db.session.query(Account).get(id_) assert account.imap_endpoint == ( account_data.imap_server_host, account_data.imap_server_port, ) assert account.smtp_endpoint == ( account_data.smtp_server_host, account_data.smtp_server_port, ) # Ensure that the emailed events calendar was created assert account._emailed_events_calendar is not None assert account._emailed_events_calendar.name == "Emailed events"
def test_successful_reauth_resets_sync_state(db, mock_imapclient): email = account_data.email password = account_data.imap_password mock_imapclient._add_login(email, password) handler = GenericAuthHandler() account = handler.create_account(account_data) assert handler.verify_account(account) is True # Brand new accounts have `sync_state`=None. assert account.sync_state is None db.session.add(account) db.session.commit() # Pretend account sync starts, and subsequently the password changes, # causing the account to be in `sync_state`='invalid'. account.mark_invalid() db.session.commit() assert account.sync_state == "invalid" # Verify the `sync_state` is reset to 'running' on a successful "re-auth". account = handler.update_account(account, account_data) assert handler.verify_account(account) is True assert account.sync_state == "running" db.session.add(account) db.session.commit()
def test_imap_not_fully_enabled(monkeypatch): def folder_list_fail(conn): raise Exception("LIST failed: '[ALERT] full IMAP support " "is NOT enabled for this account'") monkeypatch.setattr('imapclient.IMAPClient.list_folders', folder_list_fail) def fake_connect(account): return MockIMAPClient() response = { 'email': '*****@*****.**', 'password': '******', 'imap_server_host': '0.0.0.0', 'imap_server_port': 22, 'smtp_server_host': '0.0.0.0', 'smtp_server_port': 23 } handler = GenericAuthHandler('custom') acct = handler.create_account( '*****@*****.**', response) handler.connect_account = fake_connect handler._supports_condstore = lambda x: True with pytest.raises(UserRecoverableConfigError): verified = handler.verify_account(acct) assert verified is not True
def test_successful_reauth_resets_sync_state(db): settings = { 'provider': 'yahoo', 'settings': { 'name': 'Y.Y!', 'locale': 'fr', 'email': '*****@*****.**', 'password': '******' } } email = settings['settings']['email'] handler = GenericAuthHandler(settings['provider']) account = handler.create_account(email, settings['settings']) assert handler.verify_account(account) is True # Brand new accounts have `sync_state`=None. assert account.sync_state is None db.session.add(account) db.session.commit() # Pretend account sync starts, and subsequently the password changes, # causing the account to be in `sync_state`='invalid'. account.mark_invalid() db.session.commit() assert account.sync_state == 'invalid' # Verify the `sync_state` is reset to 'running' on a successful "re-auth". account = handler.update_account(account, settings['settings']) assert handler.verify_account(account) is True assert account.sync_state == 'running' db.session.add(account) db.session.commit()
def test_update_account_with_different_subdomain(db, monkeypatch): # Check that you can update the server endpoints for an account # provided that # 1/ they're on a subdomain of the same domain name. # 2/ they have the same IP address. # # To test this we use Microsoft's Office365 setup, which # has mail.office365.com and outlook.office365.com point to # the same address. updated_data = attr.evolve( account_data, imap_server_host="outlook.office365.com", smtp_server_host="outlook.office365.com", ) handler = GenericAuthHandler() # Create an authenticated account account = handler.create_account(updated_data) db.session.add(account) db.session.commit() id_ = account.id def gethostbyname_patch(x): return "127.0.0.1" monkeypatch.setattr(socket, "gethostbyname", gethostbyname_patch) # A valid update updated_data = attr.evolve( account_data, imap_server_host="mail.office365.com", smtp_server_host="mail.office365.com", ) account = handler.update_account(account, updated_data) db.session.add(account) db.session.commit() account = db.session.query(Account).get(id_) assert account._imap_server_host == "mail.office365.com" assert account._smtp_server_host == "mail.office365.com"
def test_update_account_with_different_subdomain(db, monkeypatch): # Check that you can update the server endpoints for an account # provided that # 1/ they're on a subdomain of the same domain name. # 2/ they have the same IP address. # # To test this we use Microsoft's Office365 setup, which # has mail.office365.com and outlook.office365.com point to # the same address. email = settings['settings']['email'] settings['settings']['imap_server_host'] = 'outlook.office365.com' settings['settings']['smtp_server_host'] = 'outlook.office365.com' handler = GenericAuthHandler(settings['provider']) # Create an authenticated account account = handler.create_account(email, settings['settings']) db.session.add(account) db.session.commit() id_ = account.id def gethostbyname_patch(x): return "127.0.0.1" monkeypatch.setattr(socket, 'gethostbyname', gethostbyname_patch) # A valid update updated_settings = copy.deepcopy(settings) updated_settings['settings']['imap_server_host'] = 'mail.office365.com' updated_settings['settings']['smtp_server_host'] = 'mail.office365.com' updated_settings['settings']['name'] = 'Neu!' account = handler.update_account(account, updated_settings['settings']) db.session.add(account) db.session.commit() account = db.session.query(Account).get(id_) assert account.name == 'Neu!' assert account._imap_server_host == 'mail.office365.com' assert account._smtp_server_host == 'mail.office365.com'
def create_account(): """ Create a new account """ data = request.get_json(force=True) if data["type"] == "generic": auth_handler = GenericAuthHandler() account_data = _get_account_data_for_generic_account(data) elif data["type"] == "gmail": auth_handler = GoogleAuthHandler() account_data = _get_account_data_for_google_account(data) elif data["type"] == "microsoft": auth_handler = MicrosoftAuthHandler() account_data = _get_account_data_for_microsoft_account(data) else: raise ValueError("Account type not supported.") with global_session_scope() as db_session: account = auth_handler.create_account(account_data) db_session.add(account) db_session.commit() encoder = APIEncoder() return encoder.jsonify(account.namespace)
def test_update_account(db): email = settings['settings']['email'] imap_host = settings['settings']['imap_server_host'] imap_port = settings['settings']['imap_server_port'] smtp_host = settings['settings']['smtp_server_host'] smtp_port = settings['settings']['smtp_server_port'] handler = GenericAuthHandler(settings['provider']) # Create an authenticated account account = handler.create_account(email, settings['settings']) db.session.add(account) db.session.commit() id_ = account.id # A valid update updated_settings = copy.deepcopy(settings) updated_settings['settings']['name'] = 'Neu!' account = handler.update_account(account, updated_settings['settings']) db.session.add(account) db.session.commit() account = db.session.query(Account).get(id_) assert account.name == 'Neu!' # Invalid updates for (attr, value, updated_settings) in generate_endpoint_updates(settings): assert value in updated_settings['settings'].values() with pytest.raises(UserRecoverableConfigError): account = handler.update_account(account, updated_settings['settings']) db.session.add(account) db.session.commit() account = db.session.query(Account).get(id_) assert getattr(account, attr) != value assert account.imap_endpoint == (imap_host, imap_port) assert account.smtp_endpoint == (smtp_host, smtp_port)
def folder_sync_engine(db): from inbox.mailsync.backends.imap.generic import FolderSyncEngine # setup a dummy FolderSyncEngine - we only need to call a couple # methods. email = "*****@*****.**" account = GenericAuthHandler('fastmail').create_account( db.session, email, {"email": email, "password": "******"}) db.session.add(account) db.session.commit() engine = None engine = FolderSyncEngine(account.id, "Inbox", 0, email, "fastmail", None) return engine
def test_update_account(db): email = settings['settings']['email'] imap_host = settings['settings']['imap_server_host'] imap_port = settings['settings']['imap_server_port'] smtp_host = settings['settings']['smtp_server_host'] smtp_port = settings['settings']['smtp_server_port'] handler = GenericAuthHandler(settings['provider']) # Create an authenticated account account = handler.create_account(email, settings['settings']) db.session.add(account) db.session.commit() id_ = account.id # A valid update updated_settings = copy.deepcopy(settings) updated_settings['settings']['name'] = 'Neu!' account = handler.update_account(account, updated_settings['settings']) db.session.add(account) db.session.commit() account = db.session.query(Account).get(id_) assert account.name == 'Neu!' # Invalid updates for (attr, value, updated_settings) in generate_endpoint_updates(settings): assert value in updated_settings['settings'].values() with pytest.raises(SettingUpdateError): account = handler.update_account(account, updated_settings['settings']) db.session.add(account) db.session.commit() account = db.session.query(Account).get(id_) assert getattr(account, attr) != value assert account.imap_endpoint == (imap_host, imap_port) assert account.smtp_endpoint == (smtp_host, smtp_port)
def test_double_auth(db): settings = { 'provider': 'yahoo', 'settings': { 'name': 'Y.Y!', 'locale': 'fr', 'email': '*****@*****.**', 'password': '******' } } email = settings['settings']['email'] password = settings['settings']['password'] handler = GenericAuthHandler(settings['provider']) # First authentication, using a valid password, succeeds. valid_settings = copy.deepcopy(settings) account = handler.create_account(email, valid_settings['settings']) assert handler.verify_account(account) is True db.session.add(account) db.session.commit() id_ = account.id account = db.session.query(Account).get(id_) assert account.email_address == email assert account.imap_username == email assert account.smtp_username == email assert account.password == password assert account.imap_password == password assert account.smtp_password == password # Second auth using an invalid password should fail. invalid_settings = copy.deepcopy(settings) invalid_settings['settings']['password'] = '******' with pytest.raises(ValidationError): account = handler.update_account(account, invalid_settings['settings']) handler.verify_account(account) db.session.expire(account) # Ensure original account is unaffected account = db.session.query(Account).get(id_) assert account.email_address == email assert account.imap_username == email assert account.smtp_username == email assert account.password == password assert account.imap_password == password assert account.smtp_password == password
def folder_sync_engine(db, monkeypatch): # super ugly, but I don't want to have to mock tons of stuff import inbox.mailsync.backends.imap.generic from inbox.mailsync.backends.imap.generic import FolderSyncEngine monkeypatch.setattr(inbox.mailsync.backends.imap.generic, "_pool", lambda(account): True) # setup a dummy FolderSyncEngine - we only need to call a couple # methods. email = "*****@*****.**" account = GenericAuthHandler('fastmail').create_account( db.session, email, {"email": email, "password": "******"}) db.session.add(account) db.session.commit() engine = None engine = FolderSyncEngine(account.id, "Inbox", 0, email, "fastmail", 3200, None, 20, None) return engine
def test_double_auth(db, mock_auth_imapclient): settings = { 'provider': 'yahoo', 'settings': { 'name': 'Y.Y!', 'locale': 'fr', 'email': '*****@*****.**', 'password': '******'} } email = settings['settings']['email'] password = settings['settings']['password'] mock_auth_imapclient._add_login(email, password) handler = GenericAuthHandler(settings['provider']) # First authentication, using a valid password, succeeds. valid_settings = copy.deepcopy(settings) account = handler.create_account(email, valid_settings['settings']) assert handler.verify_account(account) is True db.session.add(account) db.session.commit() id_ = account.id account = db.session.query(Account).get(id_) assert account.email_address == email assert account.imap_username == email assert account.smtp_username == email assert account.password == password assert account.imap_password == password assert account.smtp_password == password # Second auth using an invalid password should fail. invalid_settings = copy.deepcopy(settings) invalid_settings['settings']['password'] = '******' with pytest.raises(ValidationError): account = handler.update_account(account, invalid_settings['settings']) handler.verify_account(account) db.session.expire(account) # Ensure original account is unaffected account = db.session.query(Account).get(id_) assert account.email_address == email assert account.imap_username == email assert account.smtp_username == email assert account.password == password assert account.imap_password == password assert account.smtp_password == password
def test_double_auth(db, mock_imapclient): password = "******" email = account_data.email mock_imapclient._add_login(email, password) handler = GenericAuthHandler() # First authentication, using a valid password, succeeds. valid_settings = attr.evolve(account_data, imap_password=password, smtp_password=password) account = handler.create_account(valid_settings) assert handler.verify_account(account) is True db.session.add(account) db.session.commit() id_ = account.id account = db.session.query(Account).get(id_) assert account.email_address == email assert account.imap_username == email assert account.smtp_username == email assert account.imap_password == password assert account.smtp_password == password # Second auth using an invalid password should fail. invalid_settings = attr.evolve(account_data, imap_password="******") with pytest.raises(ValidationError): account = handler.update_account(account, invalid_settings) handler.verify_account(account) db.session.expire(account) # Ensure original account is unaffected account = db.session.query(Account).get(id_) assert account.email_address == email assert account.imap_username == email assert account.smtp_username == email assert account.imap_password == password assert account.smtp_password == password
def test_auth(creds, mock_imapclient): imap_username = creds['settings'].get('imap_username') if imap_username is None: imap_username = creds['settings']['email'] imap_password = creds['settings'].get('imap_password') if imap_password is None: imap_password = creds['settings']['password'] mock_imapclient._add_login(imap_username, imap_password) handler = GenericAuthHandler(creds['provider']) email = creds['settings']['email'] account = handler.create_account(email, creds['settings']) # Test that the account was successfully created by the handler. assert account.imap_password == imap_password if 'smtp_password' in creds['settings']: assert account.smtp_password == creds['settings']['smtp_password'] else: assert account.imap_password == creds['settings']['password'] assert account.smtp_password == creds['settings']['password'] # Test that the account is valid. assert handler.verify_account(account) is True # Test that the password can be updated... bad_creds = {'email': creds['settings']['email'], 'imap_password': '******', 'imap_server_host': creds['settings'].get('imap_server_host'), 'imap_server_port': 993, 'smtp_server_host': creds['settings'].get('smtp_server_host'), 'smtp_server_port': 587 } handler.update_account(account, bad_creds) assert account.imap_password == 'bad_password' # ...but logging in again won't work. with pytest.raises(ValidationError): handler.verify_account(account)
def yahoo_account(db): account = GenericAuthHandler().create_account(yahoo_account_data) db.session.add(account) db.session.commit() return account