def test_pickle(self): # Test that we can pickle various objects item = Message(folder=self.account.inbox, subject='XXX', categories=self.categories).save() attachment = FileAttachment(name='pickle_me.txt', content=b'') try: for o in ( item, attachment, self.account.protocol, self.account.root, self.account.inbox, self.account, Credentials('XXX', 'YYY'), FaultTolerance(max_wait=3600), ): pickled_o = pickle.dumps(o) unpickled_o = pickle.loads(pickled_o) self.assertIsInstance(unpickled_o, type(o)) if not isinstance(o, (Account, Protocol, FaultTolerance)): # __eq__ is not defined on some classes self.assertEqual(o, unpickled_o) finally: item.delete()
def initialize_exchange_client(self, password=None): acc_credentials = Credentials(username=self.email_address, password=password) version = Version(build=Build(config.EXCHANGE_VERSION['major'], config.EXCHANGE_VERSION['minor'])) acc_config = Configuration(service_endpoint=config.EXCHANGE_URL, credentials=acc_credentials, auth_type='basic', version=version, retry_policy=FaultTolerance(max_wait=300)) self.exchange_client = Account(primary_smtp_address=self.email_address, config=acc_config, autodiscover=True, access_type='delegate')
def _generate_state(self, sm): service_account = Credentials( username=self._admin_user, password=self._admin_password) config = Configuration( retry_policy=FaultTolerance(max_wait=1800), service_endpoint=self._server, credentials=service_account if self._server else None) try: account = Account( primary_smtp_address=self.address, credentials=service_account, config=config, autodiscover=not bool(self._server), access_type=IMPERSONATION) except ErrorNonExistentMailbox as e: raise ResourceUnavailableError(self, e.args) try: yield account finally: # XXX: we should, in principle, close account.protocol here, but # exchangelib seems to keep a reference to it internally and so # waits forever if we do pass
def __init__(self, email: Email, config: EWSConfig): self._email = email self._config = config self._gcs_client = storage.Client() credentials = Credentials(config.email_account, config.password) version = Version(build=Build(config.exchange_version["major"], config.exchange_version["minor"])) ews_config = Configuration( service_endpoint=config.exchange_url, credentials=credentials, auth_type="basic", version=version, retry_policy=FaultTolerance(max_wait=300), ) self._account = Account( primary_smtp_address=config.email_account, config=ews_config, autodiscover=False, access_type="delegate", ) # Setup reply-mail client. recipient = "" if self._config.hardcoded_recipients: recipient = self._config.mail_to_mapping.get(self._email.recipient) else: recipient = self._config.mail_to_mapping.get("STANDARD") acc_credentials = Credentials( username=recipient["sender_account"], password=util.get_secret(os.environ["PROJECT_ID"], recipient["sender_account_secret"]), ) acc_config = Configuration( service_endpoint=config.exchange_url, credentials=acc_credentials, auth_type="basic", version=version, retry_policy=FaultTolerance(max_wait=300), ) self._reply_email_account = Account( primary_smtp_address=recipient["sender_account"], config=acc_config, autodiscover=False, access_type="delegate", )
def test_service_account_back_off(self): # Test back-off logic in FaultTolerance sa = FaultTolerance() # Initially, the value is None self.assertIsNone(sa.back_off_until) # Test a non-expired back off value in_a_while = datetime.datetime.now() + datetime.timedelta(seconds=10) sa.back_off_until = in_a_while self.assertEqual(sa.back_off_until, in_a_while) # Test an expired back off value sa.back_off_until = datetime.datetime.now() time.sleep(0.001) self.assertIsNone(sa.back_off_until) # Test the back_off() helper sa.back_off(10) # This is not a precise test. Assuming fast computers, there should be less than 1 second between the two lines. self.assertEqual( int( math.ceil((sa.back_off_until - datetime.datetime.now()).total_seconds())), 10) # Test expiry sa.back_off(0) time.sleep(0.001) self.assertIsNone(sa.back_off_until) # Test default value sa.back_off(None) self.assertEqual( int( math.ceil((sa.back_off_until - datetime.datetime.now()).total_seconds())), 60)
def __init__( self, auth_address=None, password=None, alias=None, proxy=None, logger=None, **kwargs, ): self.logger = logger or logging.getLogger(__name__) config = grizly_config.get_service("email") self.address = (auth_address or config.get("auth_address") or config.get("address") or os.getenv("GRIZLY_EMAIL_ADDRESS")) self.password = password or os.getenv( "GRIZLY_EMAIL_PASSWORD") or config.get("password") if None in (self.address, self.password): raise ValueError("Email address or password not found") self.alias = alias self.credentials = Credentials(self.address, self.password) self.config = Configuration( server="smtp.office365.com", credentials=self.credentials, retry_policy=FaultTolerance(max_wait=60), ) self.proxy = (proxy or os.getenv("GRIZLY_PROXY") or os.getenv("HTTPS_PROXY") or grizly_config.get_service("proxies").get("https")) if self.proxy: os.environ["HTTPS_PROXY"] = self.proxy try: smtp_address = self.address if self.alias: smtp_address = self.alias self.account = Account( primary_smtp_address=smtp_address, credentials=self.credentials, config=self.config, autodiscover=False, access_type=DELEGATE, ) except: self.logger.exception( f"Email account {self.address}, proxy: {self.proxy if self.proxy else ''} could not be accessed." ) raise ConnectionError( "Connection to Exchange server failed. Please check your credentials and/or proxy settings" )
def create_config(self, credentials, m_config=None): if m_config is None: # failed once, use hardcoded vals service_endpoint = 'https://outlook.office365.com/EWS/Exchange.asmx' auth_type = 'basic' version = None else: service_endpoint = m_config.get('ews_url', None) auth_type = m_config.get('ews_auth_type', None) version = m_config.get('ews_version', None) config = Configuration(retry_policy=FaultTolerance(max_wait=40), credentials=credentials, service_endpoint=service_endpoint, auth_type=auth_type, version=version) return config
def test_post_ratelimited(self): url = 'https://example.com' protocol = self.account.protocol retry_policy = protocol.config.retry_policy RETRY_WAIT = exchangelib.util.RETRY_WAIT MAX_REDIRECTS = exchangelib.util.MAX_REDIRECTS session = protocol.get_session() try: # Make sure we fail fast in error cases protocol.config.retry_policy = FailFast() # Test the straight, HTTP 200 path session.post = mock_post(url, 200, {}, 'foo') r, session = post_ratelimited(protocol=protocol, session=session, url='http://', headers=None, data='') self.assertEqual(r.content, b'foo') # Test exceptions raises by the POST request for err_cls in CONNECTION_ERRORS: session.post = mock_session_exception(err_cls) with self.assertRaises(err_cls): r, session = post_ratelimited( protocol=protocol, session=session, url='http://', headers=None, data='') # Test bad exit codes and headers session.post = mock_post(url, 401, {}) with self.assertRaises(UnauthorizedError): r, session = post_ratelimited(protocol=protocol, session=session, url='http://', headers=None, data='') session.post = mock_post(url, 999, {'connection': 'close'}) with self.assertRaises(TransportError): r, session = post_ratelimited(protocol=protocol, session=session, url='http://', headers=None, data='') session.post = mock_post(url, 302, {'location': '/ews/genericerrorpage.htm?aspxerrorpath=/ews/exchange.asmx'}) with self.assertRaises(TransportError): r, session = post_ratelimited(protocol=protocol, session=session, url='http://', headers=None, data='') session.post = mock_post(url, 503, {}) with self.assertRaises(TransportError): r, session = post_ratelimited(protocol=protocol, session=session, url='http://', headers=None, data='') # No redirect header session.post = mock_post(url, 302, {}) with self.assertRaises(TransportError): r, session = post_ratelimited(protocol=protocol, session=session, url=url, headers=None, data='') # Redirect header to same location session.post = mock_post(url, 302, {'location': url}) with self.assertRaises(TransportError): r, session = post_ratelimited(protocol=protocol, session=session, url=url, headers=None, data='') # Redirect header to relative location session.post = mock_post(url, 302, {'location': url + '/foo'}) with self.assertRaises(RedirectError): r, session = post_ratelimited(protocol=protocol, session=session, url=url, headers=None, data='') # Redirect header to other location and allow_redirects=False session.post = mock_post(url, 302, {'location': 'https://contoso.com'}) with self.assertRaises(TransportError): r, session = post_ratelimited(protocol=protocol, session=session, url=url, headers=None, data='') # Redirect header to other location and allow_redirects=True exchangelib.util.MAX_REDIRECTS = 0 session.post = mock_post(url, 302, {'location': 'https://contoso.com'}) with self.assertRaises(TransportError): r, session = post_ratelimited(protocol=protocol, session=session, url=url, headers=None, data='', allow_redirects=True) # CAS error session.post = mock_post(url, 999, {'X-CasErrorCode': 'AAARGH!'}) with self.assertRaises(CASError): r, session = post_ratelimited(protocol=protocol, session=session, url=url, headers=None, data='') # Allow XML data in a non-HTTP 200 response session.post = mock_post(url, 500, {}, '<?xml version="1.0" ?><foo></foo>') r, session = post_ratelimited(protocol=protocol, session=session, url=url, headers=None, data='') self.assertEqual(r.content, b'<?xml version="1.0" ?><foo></foo>') # Bad status_code and bad text session.post = mock_post(url, 999, {}) with self.assertRaises(TransportError): r, session = post_ratelimited(protocol=protocol, session=session, url=url, headers=None, data='') # Test rate limit exceeded exchangelib.util.RETRY_WAIT = 1 protocol.config.retry_policy = FaultTolerance(max_wait=0.5) # Fail after first RETRY_WAIT session.post = mock_post(url, 503, {'connection': 'close'}) # Mock renew_session to return the same session so the session object's 'post' method is still mocked protocol.renew_session = lambda s: s with self.assertRaises(RateLimitError) as rle: r, session = post_ratelimited(protocol=protocol, session=session, url='http://', headers=None, data='') self.assertEqual(rle.exception.status_code, 503) self.assertEqual(rle.exception.url, url) self.assertTrue(1 <= rle.exception.total_wait < 2) # One RETRY_WAIT plus some overhead # Test something larger than the default wait, so we retry at least once protocol.retry_policy.max_wait = 3 # Fail after second RETRY_WAIT session.post = mock_post(url, 503, {'connection': 'close'}) with self.assertRaises(RateLimitError) as rle: r, session = post_ratelimited(protocol=protocol, session=session, url='http://', headers=None, data='') self.assertEqual(rle.exception.status_code, 503) self.assertEqual(rle.exception.url, url) # We double the wait for each retry, so this is RETRY_WAIT + 2*RETRY_WAIT plus some overhead self.assertTrue(3 <= rle.exception.total_wait < 4, rle.exception.total_wait) finally: protocol.retire_session(session) # We have patched the session, so discard it # Restore patched attributes and functions protocol.config.retry_policy = retry_policy exchangelib.util.RETRY_WAIT = RETRY_WAIT exchangelib.util.MAX_REDIRECTS = MAX_REDIRECTS try: delattr(protocol, 'renew_session') except AttributeError: pass
def get_accounts(**config): """ get a list of working Exchange accounts This function expects that each Exchange account is described by the ``config`` argument as shown in the ``JSON`` snippet below. A full representation of the structure of the ``config`` argument as used in the :ref:`Mail Borg Client Application` is available in the :ref:`borg_client_config` section. .. code-block:: json { "smtp_address":"*****@*****.**", "domain_account": { "domain":"PHSABC", "username":"******", "password":"******" }, "exchange_autodiscover":true, "autodiscover_server":null } :arg dict config: a :class:`dictionary <dict>` that matches the structure described in :ref:`borg_client_config` (or the relevant portions thereof) As used in the :ref:`Mail Borg Client Application`, the ``config`` argument is provided via an :attr:`WitnessMessages.config` instance attribute :returns: :class:`list` of :class:`exchangelib.Account` objects An :class:`exchangelib.Account` object is only created if this module was able to connect to the EWS end point using the provided credentials. If an Exchange account entry in the ``config`` argument cannot be used to create a valid :class:`exchangelib.Account` instance, an error will be logged and there will be no matching entry in the return. If none of the Exchange account entries in the ``config`` argument can be used to create a valid :class:`exchangelib.Account` instance, an error will be logged and the function will return ``None`` """ if not config: config = load_config() logger = _Logger() accounts = [] exchange_accounts = config.get('exchange_client_config').\ get('exchange_accounts') for exchange_account in exchange_accounts: if not validate_email_to_ascii(exchange_account.get('smtp_address'), ** config): continue credentials = Credentials( username='******'.format( exchange_account.get('domain_account').get('domain'), exchange_account.get('domain_account').get('username')), password=exchange_account.get('domain_account').get('password')) try: if exchange_account.get('exchange_autodiscover', True): exc_config = Configuration(credentials=credentials, retry_policy=FaultTolerance()) accounts.append( Account(primary_smtp_address=exchange_account.get( 'smtp_address'), config=exc_config, autodiscover=True, access_type=DELEGATE)) else: exc_config = Configuration( server=exchange_account.get('autodiscover_server'), credentials=credentials, retry_policy=FaultTolerance()) accounts.append( Account(primary_smtp_address=exchange_account.get( 'smtp_address'), config=exc_config, autodiscover=False, access_type=DELEGATE)) logger.info( dict( type='connection', status='PASS', wm_id=config.get('wm_id'), message='connected to exchange', account='{}\\{}, {}'.format( exchange_account.get('domain_account').get('domain'), exchange_account.get('domain_account').get('username'), exchange_account.get('smtp_address')))) except Exception as error: logger.err( dict( type='connection', status='FAIL', wm_id=config.get('wm_id'), message='cannot connect to exchange', account='{}\\{}, {}'.format( exchange_account.get('domain_account').get('domain'), exchange_account.get('domain_account').get('username'), exchange_account.get('smtp_address')), exeption=str(error))) if not accounts: logger.err( dict(type='configuration', status='FAIL', wm_id=config.get('wm_id'), account=None, message=( 'no valid exchange account found in config for bot %s' % config.get('host_name')))) return None return accounts
'Copy settings.yml.sample to settings.yml and enter values for your test server' ) raise categories = ['perftest'] tz = zoneinfo.ZoneInfo('America/New_York') verify_ssl = settings.get('verify_ssl', True) if not verify_ssl: from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter config = Configuration( server=settings['server'], credentials=Credentials(settings['username'], settings['password']), retry_policy=FaultTolerance(), ) print(f'Exchange server: {config.service_endpoint}') account = Account(config=config, primary_smtp_address=settings['account'], access_type=DELEGATE) # Remove leftovers from earlier tests account.calendar.filter(categories__contains=categories).delete() # Calendar item generator def generate_items(count): start = datetime.datetime(2000, 3, 1, 8, 30, 0, tzinfo=tz) end = datetime.datetime(2000, 3, 1, 9, 15, 0, tzinfo=tz)
from exchangelib import DELEGATE, IMPERSONATION, Message, Account, HTMLBody, Credentials, Configuration, NTLM, FaultTolerance, CalendarItem, EWSDateTime from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter from exchangelib.items import MeetingRequest, SEND_TO_ALL_AND_SAVE_COPY from exchangelib.recurrence import Recurrence, WeeklyPattern from exchangelib.fields import WEEK_DAY, MONDAY from time import sleep from datetime import timedelta, datetime from threading import Thread import requests BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter credentials = Credentials(username='******', password='******') config = Configuration(retry_policy=FaultTolerance(max_wait=3600), server="192.168.10.118", credentials=credentials, auth_type=NTLM) user_one = Account(primary_smtp_address='*****@*****.**', credentials=credentials, autodiscover=False, config=config, access_type=DELEGATE) r1 = Account(primary_smtp_address='*****@*****.**', credentials=credentials, autodiscover=False, config=config, access_type=DELEGATE) r2 = Account(primary_smtp_address='*****@*****.**', credentials=credentials,
from exchangelib import DELEGATE, IMPERSONATION, Message, Account, HTMLBody, Credentials, Configuration, NTLM, FaultTolerance, CalendarItem, EWSDateTime from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter from exchangelib.items import MeetingRequest, SEND_TO_ALL_AND_SAVE_COPY from exchangelib.recurrence import Recurrence, WeeklyPattern from exchangelib.fields import WEEK_DAY, MONDAY from time import sleep from datetime import timedelta, datetime BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter # credentials = Credentials(username='******', password='******') credentials = Credentials(username='******', password='******') config = Configuration(retry_policy=FaultTolerance(max_wait=3600), server="192.168.10.118", credentials=credentials, auth_type=NTLM) user_one = Account(primary_smtp_address='*****@*****.**', credentials=credentials, autodiscover=False, config=config, access_type=DELEGATE) user_two = Account(primary_smtp_address='*****@*****.**', credentials=credentials, autodiscover=False, config=config, access_type=DELEGATE) item_1 = CalendarItem( account = user_one, folder = user_one.calendar, start = user_one.default_timezone.localize(EWSDateTime(2021, 1, 21, 17, 00)), end = user_one.default_timezone.localize(EWSDateTime(2021, 1, 21, 18, 00)), location = "testroom1", subject = "Meeting Test", body = "Test 1", required_attendees = ['*****@*****.**', '*****@*****.**'] ) item_2 = CalendarItem( account = user_two,
def test_post_ratelimited(self): url = 'https://example.com' protocol = self.account.protocol retry_policy = protocol.config.retry_policy renew_session = protocol.renew_session session = protocol.get_session() try: # Make sure we fail fast in error cases protocol.config.retry_policy = FailFast() # Test the straight, HTTP 200 path session.post = mock_post(url, 200, {}, 'foo') r, session = post_ratelimited(protocol=protocol, session=session, url='http://', headers=None, data='') self.assertEqual(r.content, b'foo') # Test exceptions raises by the POST request for err_cls in CONNECTION_ERRORS: session.post = mock_session_exception(err_cls) with self.assertRaises(err_cls): r, session = post_ratelimited(protocol=protocol, session=session, url='http://', headers=None, data='') # Test bad exit codes and headers session.post = mock_post(url, 401, {}) with self.assertRaises(UnauthorizedError): r, session = post_ratelimited(protocol=protocol, session=session, url='http://', headers=None, data='') session.post = mock_post(url, 999, {'connection': 'close'}) with self.assertRaises(TransportError): r, session = post_ratelimited(protocol=protocol, session=session, url='http://', headers=None, data='') session.post = mock_post( url, 302, { 'location': '/ews/genericerrorpage.htm?aspxerrorpath=/ews/exchange.asmx' }) with self.assertRaises(TransportError): r, session = post_ratelimited(protocol=protocol, session=session, url='http://', headers=None, data='') session.post = mock_post(url, 503, {}) with self.assertRaises(TransportError): r, session = post_ratelimited(protocol=protocol, session=session, url='http://', headers=None, data='') # No redirect header session.post = mock_post(url, 302, {}) with self.assertRaises(TransportError): r, session = post_ratelimited(protocol=protocol, session=session, url=url, headers=None, data='') # Redirect header to same location session.post = mock_post(url, 302, {'location': url}) with self.assertRaises(TransportError): r, session = post_ratelimited(protocol=protocol, session=session, url=url, headers=None, data='') # Redirect header to relative location session.post = mock_post(url, 302, {'location': url + '/foo'}) with self.assertRaises(RedirectError): r, session = post_ratelimited(protocol=protocol, session=session, url=url, headers=None, data='') # Redirect header to other location and allow_redirects=False session.post = mock_post(url, 302, {'location': 'https://contoso.com'}) with self.assertRaises(TransportError): r, session = post_ratelimited(protocol=protocol, session=session, url=url, headers=None, data='') # Redirect header to other location and allow_redirects=True import exchangelib.util exchangelib.util.MAX_REDIRECTS = 0 session.post = mock_post(url, 302, {'location': 'https://contoso.com'}) with self.assertRaises(TransportError): r, session = post_ratelimited(protocol=protocol, session=session, url=url, headers=None, data='', allow_redirects=True) # CAS error session.post = mock_post(url, 999, {'X-CasErrorCode': 'AAARGH!'}) with self.assertRaises(CASError): r, session = post_ratelimited(protocol=protocol, session=session, url=url, headers=None, data='') # Allow XML data in a non-HTTP 200 response session.post = mock_post(url, 500, {}, '<?xml version="1.0" ?><foo></foo>') r, session = post_ratelimited(protocol=protocol, session=session, url=url, headers=None, data='') self.assertEqual(r.content, b'<?xml version="1.0" ?><foo></foo>') # Bad status_code and bad text session.post = mock_post(url, 999, {}) with self.assertRaises(TransportError): r, session = post_ratelimited(protocol=protocol, session=session, url=url, headers=None, data='') # Rate limit exceeded protocol.config.retry_policy = FaultTolerance(max_wait=1) session.post = mock_post(url, 503, {'connection': 'close'}) protocol.renew_session = lambda s: s # Return the same session so it's still mocked with self.assertRaises(RateLimitError) as rle: r, session = post_ratelimited(protocol=protocol, session=session, url='http://', headers=None, data='') self.assertEqual( str(rle.exception), 'Max timeout reached (gave up after 10 seconds. URL https://example.com returned status code 503)' ) self.assertEqual(rle.exception.url, url) self.assertEqual(rle.exception.status_code, 503) # Test something larger than the default wait, so we retry at least once protocol.retry_policy.max_wait = 15 session.post = mock_post(url, 503, {'connection': 'close'}) with self.assertRaises(RateLimitError) as rle: r, session = post_ratelimited(protocol=protocol, session=session, url='http://', headers=None, data='') self.assertEqual( str(rle.exception), 'Max timeout reached (gave up after 20 seconds. URL https://example.com returned status code 503)' ) self.assertEqual(rle.exception.url, url) self.assertEqual(rle.exception.status_code, 503) finally: protocol.retire_session( session) # We have patched the session, so discard it # Restore patched attributes and functions protocol.config.retry_policy = retry_policy protocol.renew_session = renew_session
from my_variables import master_alias, mmm_dict import time import stdiomask from exchangelib import DELEGATE, Account, Credentials, Configuration, FileAttachment, ItemAttachment, Message, CalendarItem, HTMLBody, Mailbox, FaultTolerance, HTMLBody try: ad_password = stdiomask.getpass(prompt= 'Enter Active Directory Password: '******'*') except Exception as error: print('ERROR', error) #credentials are the domain name with username and password creds = Credentials(username='******', password=ad_password) #account configuration config = Configuration(server='HSCLink.health.unm.edu', credentials=creds, retry_policy=FaultTolerance(max_wait=3600)) a = Account('*****@*****.**', credentials=creds, autodiscover=True) #set the thresholds for testing and screening hours difference hrs_screen_threshold = 36 hrs_test_threshold = 72 max_pd_display() #define the file paths and file names0 data_path = Path('//uh-nas/Groupshare3/ClinicalAdvisoryTeam/data_folders/8940_covid_screen') support_path = Path('//uh-nas/Groupshare3/ClinicalAdvisoryTeam/data_folders/support_files') archive_path = Path('//uh-nas/Groupshare3/ClinicalAdvisoryTeam/data_folders/8940_covid_screen/8940_archive') file_name = '#8940 Covid Screen.xlsx'
def parse_account_config(self, account_defn): """ Produce an `exchangelib.Account` object from our configuration :arg dict account_defn: A dictionary which contains a definition of a smtp account, which includes an smtp_address string, domain_account dictionary, exchange_autodiscover boolean, autodiscover_server string (if autodiscover is false). :returns: The `exchangelib.Account` described by the input, or None if the input is malformed. """ if not validate_email_to_ascii(account_defn.get('smtp_address')): return credentials = Credentials( username='******'.format( account_defn.get('domain_account').get('domain'), account_defn.get('domain_account').get('username')), password=account_defn.get('domain_account').get('password')) try: if account_defn.get('exchange_autodiscover', True): exc_config = Configuration(credentials=credentials, retry_policy=FaultTolerance()) account = Account( primary_smtp_address=account_defn.get('smtp_address'), config=exc_config, autodiscover=True, access_type=DELEGATE) else: exc_config = Configuration( server=account_defn.get('autodiscover_server'), credentials=credentials, retry_policy=FaultTolerance()) account = Account( primary_smtp_address=account_defn.get('smtp_address'), config=exc_config, autodiscover=False, access_type=DELEGATE) self.logger.info( dict(type='connection', status='PASS', wm_id=self.config.get('wm_id'), message='connected to exchange', account='{}\\{}, {}'.format( account_defn.get('domain_account').get('domain'), account_defn.get('domain_account').get('username'), account_defn.get('smtp_address')))) except Exception as error: self.logger.err( dict(type='connection', status='FAIL', wm_id=self.config.get('wm_id'), message='cannot connect to exchange', account='{}\\{}, {}'.format( account_defn.get('domain_account').get('domain'), account_defn.get('domain_account').get('username'), account_defn.get('smtp_address')), exeption=str(error))) return return account
from exchangelib import UTC_NOW import time import stdiomask try: ad_password = stdiomask.getpass(prompt='Enter Active Directory Password: '******'*') except Exception as error: print('ERROR', error) #credentials are the domain name with username and password creds = Credentials(username='******', password=ad_password) #account configuration config = Configuration(server='HSCLink.health.unm.edu', credentials=creds, retry_policy=FaultTolerance(max_wait=3600)) #create the instance of account class object a = Account('*****@*****.**', credentials=creds, autodiscover=True) #define and create the auto_rules folder auto_folder = a.root / 'Top of Information Store' / 'auto_rules' ##list of file name text keywords in attachments to save #attachment_to_save = ['#8940', 'random_rule_check'] #generate a time difference variable for the recency of hours that messages have arrived #since = UTC_NOW() - timedelta(hours=4) #define the function with inputs (name of attachment you are looking for, file path you want to save the attachment to, and name you want to call the file) def save_attach(attach_name, path_to_save, name_to_save): #generate a time difference variable for the recency of hours that messages have arrived