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 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_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 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_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_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 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_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 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 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 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_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_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_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_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'