Giter VIP home page Giter VIP logo

Comments (29)

ecederstrand avatar ecederstrand commented on September 25, 2024 2

To everyone hitting this bug: can you please test out 3ee351a? I believe it fixes the issue.

from exchangelib.

ecederstrand avatar ecederstrand commented on September 25, 2024 1

This is unrelated to the original issue. Please open a new issue instead.

from exchangelib.

ecederstrand avatar ecederstrand commented on September 25, 2024

Thanks for the report! Can you please post the code that leads to this error?

from exchangelib.

FairWindCo avatar FairWindCo commented on September 25, 2024

this is fragment of initialization code

exchange_config = Configuration(
    auth_type=SSPI,
    retry_policy=FaultTolerance(max_wait=3600),
    server=config['exchnage_server']
)
accounts_names = config.get('accounts', [])
accounts = list([Account(
        primary_smtp_address=account_name, config=exchange_config,
        autodiscover=False, access_type=DELEGATE
    ) for account_name in accounts_names])

this is fragments telegram bot that interact with exchange

number, account_for_process = get_call_info(call) #get information for account and numbers of message to see
if account_for_process:
    mails = list(account_for_process.inbox.all().order_by('-datetime_received')[:int(number)])
    # for debug print to console
    print(f"GET LAST {number} MAILS FOR ACCOUNT {account_for_process}")
    if mails:
       # for debug print to console
       for mail in mails:
           print(mail.id)
       send_mail_info(bot, [call.message.chat.id], mails, account_for_process) #send mail info to telegram chart

for example a have [email protected] (this is my) and [email protected] (external account that I have access rights)
prior version 5.1 when I select account2 see mail from his inbox
but in version 5.1 when I select account2 see mail from account1 inbox
For debug I compare exchange message id, in version 5.1 is identical for account1 and account2
Test is code like this:

    mail_account1 = list(account[0].inbox.all().order_by('-datetime_received')[-1])
    mail_account2 = list(account[1].inbox.all().order_by('-datetime_received')[-1])
    assert mail_account1.id != mail_account2.id, "Access to same inbox"

from exchangelib.

ecederstrand avatar ecederstrand commented on September 25, 2024

Thanks for the example!

I currently don't have a test setup with multiple accounts, so it's difficult for me to test. It may take me a while to get to. If you can do any debugging on your own, that would be most helpful. Thanks!

from exchangelib.

Glant0r avatar Glant0r commented on September 25, 2024

Hello,

I have basically the same Issue.
Prior to and including 5.0.3 it works fine, after 5.1.0 it doesnt work as expected.

I have access to 2 Mailboxes, a normal one and a shared one.
In 5.0.3 I can change between the mailboxes by changing the primary_smtp_address variable.

def makeAccount(smtp_adress):
account = Account(primary_smtp_address=smtp_adress, access_type=DELEGATE, config=config)

In 5.1.0 if I print(account) it prints the correct shared mailbox adress, but it always connects as the normal one.
The root.tree() is from the normal one and it sends emails as the normal one.

If i can be in any help diagnosing this or helping you just let me know.

from exchangelib.

platinops avatar platinops commented on September 25, 2024

I'm having the same issue. I've narrowed it down to this commit. Before that commit root.tree() returns the (correct) shared mailbox folder structure. Afterwards it returns the (faulty) normal one.

May be somewhat related to this earlier bug?

If I can do some further tests, just let me know.

from exchangelib.

lerome avatar lerome commented on September 25, 2024

Same issue here. Makes 5.1 unusable.

from exchangelib.

scottboston avatar scottboston commented on September 25, 2024

Confirmed. I am seeing the same behavior. Rolled back to previous versions.

from exchangelib.

domrim avatar domrim commented on September 25, 2024

i've done some bisecting and seems to me commit 9d45d79 introduced this bug. maybe that helps @ecederstrand ?

from exchangelib.

ecederstrand avatar ecederstrand commented on September 25, 2024

Yeah, platinops found out as well in #1222 (comment)

It's a large commit and not obvious to me how that broke the functionality described in this issue. And I don't have easy access to a multi-account test setup where I can debug.

from exchangelib.

ecederstrand avatar ecederstrand commented on September 25, 2024

I tried but failed to reproduce this issue with a credential that has access to multiple accounts:

from exchangelib import (
    OAuth2Credentials,
    Account,
    Configuration,
    OAUTH2,
    Identity,
    Mailbox,
    IMPERSONATION,
)
from exchangelib.folders import SingleFolderQuerySet, DistinguishedFolderId, Calendar


credentials = OAuth2Credentials(
    client_id="XXX",
    client_secret="YYY",
    tenant_id="ZZZ",
    identity=Identity(primary_smtp_address="[email protected]")
)

config = Configuration(server="outlook.office365.com", auth_type=OAUTH2, credentials=credentials)
accounts = "[email protected]", "[email protected]"
for email, shared_email in zip(accounts, reversed(accounts)):
    a = Account(primary_smtp_address=email, access_type=IMPERSONATION, config=config, autodiscover=False)
    print(a.primary_smtp_address, a.calendar.all().count(), a.calendar.all().order_by('-start')[0].id)
    other_folder = DistinguishedFolderId(
        id=Calendar.DISTINGUISHED_FOLDER_ID,
        mailbox=Mailbox(email_address=shared_email)
    )
    c = SingleFolderQuerySet(account=a, folder=other_folder).resolve()
    print(shared_email, c.all().count(), c.all().order_by('-start')[0].id)

This prints two different accounts, and two different counts and IDs. For SingleFolderQuerySet, it correctly prints the ID in the shared_email calendar. What am I missing?

from exchangelib.

baloo66 avatar baloo66 commented on September 25, 2024

no office365 here, on premise exchange installation: stripped down code:

credentials = Credentials('domain\userid', 'password')

config = Configuration(server='the.exchange.server.url', credentials=credentials)
account = Account(primary_smtp_address = '[email protected]', config = config, autodiscover = False, access_type = DELEGATE)

folder = account.inbox
print(folder.tree())

where the [email protected] is not the personal mailbox of domain\userid but a shared one. And: up to (and including 5.0.3) it worked and presented the inbox tree of desired-mailbox, with 5.1.0 it shows the inbox of domain\userid

from exchangelib.

lerome avatar lerome commented on September 25, 2024

Very similar code as your code here, @ecederstrand. Except that we use access_type=DELEGATE instead of IMPERSONATION. It works with 5.0.3. We tried changing access_type to IMPERSONATION but then we get "exchangelib.errors.ErrorImpersonateUserDenied: The account does not have permission to impersonate the requested user."

from exchangelib.

ecederstrand avatar ecederstrand commented on September 25, 2024

Ok. I don't have a multi-account setup with DELEGATE access, unfortunately. You'll need to debug this on your own.

I would start by enabling debug logging (see https://ecederstrand.github.io/exchangelib/#troubleshooting) to check the difference between a successful 5.03 and a failing 5.1.0 request. Posting the differences here would be useful.

from exchangelib.

hamarituc avatar hamarituc commented on September 25, 2024

My setup is affected by the problem as well. We are running an on premise Exchange server. I did the following test to compare the differences between version 5.0.3 and 5.1.0.

import exchangelib
import logging

logging.basicConfig(level = logging.DEBUG, handlers = [exchangelib.PrettyXmlHandler()])
logging.getLogger().setLevel(logging.DEBUG)

creds = exchangelib.Credentials(username = 'username', password = 'password')
config = exchangelib.Configuration(service_endpoint = 'https://server.domain/EWS/Exchange.asmx', credentials = creds, version = exchangelib.Version(build = exchangelib.Build(15, 2, 0, 0)))
account = exchangelib.Account(primary_smtp_address = 'mail@domain', autodiscover = False, config = config, access_type = exchangelib.DELEGATE)
account.identity.upn = 'upn@domain'

list(account.calendar.all())

The working version 5.0.3 resulted in the following output.

DEBUG "Starting new HTTPS connection (1): server.domain:443"
DEBUG "https://server.domain:443 "POST /EWS/Exchange.asmx HTTP/1.1" 401 0"
DEBUG "Starting new HTTPS connection (1): server.domain:443"
DEBUG "https://server.domain:443 "POST /EWS/Exchange.asmx HTTP/1.1" 401 0"
DEBUG "NTLM step input: "
DEBUG "NTLM step output: REDACTED"
DEBUG "https://server.domain:443 "POST /EWS/Exchange.asmx HTTP/1.1" 401 0"
DEBUG "NTLM step input: REDACTED"
DEBUG "NTLM step output: REDACTED"
DEBUG "https://server.domain:443 "POST /EWS/Exchange.asmx HTTP/1.1" 500 None"
DEBUG "https://server.domain:443 "POST /EWS/Exchange.asmx HTTP/1.1" 200 None"
DEBUG "https://server.domain:443 "POST /EWS/Exchange.asmx HTTP/1.1" 200 None"
DEBUG "https://server.domain:443 "POST /EWS/Exchange.asmx HTTP/1.1" 200 None"
DEBUG "https://server.domain:443 "POST /EWS/Exchange.asmx HTTP/1.1" 200 None"

The non-working version 5.1.0. resulted in the following output.

DEBUG "Starting new HTTPS connection (1): server.domain:443"
DEBUG "https://server.domain:443 "POST /EWS/Exchange.asmx HTTP/1.1" 401 0"
DEBUG "Starting new HTTPS connection (1): server.domain:443"
DEBUG "https://server.domain:443 "POST /EWS/Exchange.asmx HTTP/1.1" 401 0"
DEBUG "NTLM step input: "
DEBUG "NTLM step output: REDACTED"
DEBUG "https://server.domain:443 "POST /EWS/Exchange.asmx HTTP/1.1" 401 0"
DEBUG "NTLM step input: REDACTED"
DEBUG "NTLM step output: REDACTED"
DEBUG "https://server.domain:443 "POST /EWS/Exchange.asmx HTTP/1.1" 200 None"
DEBUG "https://server.domain:443 "POST /EWS/Exchange.asmx HTTP/1.1" 200 None"
DEBUG "https://server.domain:443 "POST /EWS/Exchange.asmx HTTP/1.1" 200 None"

Two requests are missing. Is there a possibility to trace the requests in more detail?

But maybe this information is already enough to isolate the point in 9d45d79 where a necessary request is skipped.

from exchangelib.

ecederstrand avatar ecederstrand commented on September 25, 2024

There must be more logging output than that. PrettyXmlHandler prints out the full XML request and response documents, colored and pretty-printed even. Did you perhaps log to a file or filter the log output somehow?

There's a lot going on in the pinpointed commit, and it's not clear what caused the regression. It also contains necessary fixes for other issues, so we can't just roll it back.

from exchangelib.

baloo66 avatar baloo66 commented on September 25, 2024

just tried it - goal is to do a print(folder.tree()) (see code above: #1222 (comment))

bug-test-error is the erroneous log, bug-test-ok.log the one which behaves as expected.
the only difference is the bug-test-ok was on exchangelib 5.0.3, bug-test-error with exchangelib 5.1.0

maybe it helps you - I would be glad if i can help to track down the problem

bug-test-error.log
bug-test-ok.log

from exchangelib.

Takalele avatar Takalele commented on September 25, 2024

Hi,

simple solution, we have to use DistinguishedFolderId as @ecederstrand showed us in his example

from exchangelib import (
    OAuth2Credentials,
    Account,
    Configuration,
    OAUTH2,
    Identity,
    Mailbox,
    IMPERSONATION,
)
from exchangelib.folders import SingleFolderQuerySet, DistinguishedFolderId, Calendar


credentials = OAuth2Credentials(
    client_id="XXX",
    client_secret="YYY",
    tenant_id="ZZZ",
    identity=Identity(primary_smtp_address="[email protected]")
)

config = Configuration(server="outlook.office365.com", auth_type=OAUTH2, credentials=credentials)
accounts = "[email protected]", "[email protected]"
for email, shared_email in zip(accounts, reversed(accounts)):
    a = Account(primary_smtp_address=email, access_type=IMPERSONATION, config=config, autodiscover=False)
    print(a.primary_smtp_address, a.calendar.all().count(), a.calendar.all().order_by('-start')[0].id)
    other_folder = DistinguishedFolderId(
        id=Calendar.DISTINGUISHED_FOLDER_ID,
        mailbox=Mailbox(email_address=shared_email)
    )
    c = SingleFolderQuerySet(account=a, folder=other_folder).resolve()
    print(shared_email, c.all().count(), c.all().order_by('-start')[0].id)

This prints two different accounts, and two different counts and IDs. For SingleFolderQuerySet, it correctly prints the ID in the shared_email calendar. What am I missing?

you can also take a look at this comment:
#1254 (comment)
and this issue:
#1202

BR
Takalele

from exchangelib.

hamarituc avatar hamarituc commented on September 25, 2024

simple solution, we have to use DistinguishedFolderId as @ecederstrand showed us in his example

This example solves a different problem. There are two distinct ways to access a foreign mailbox:

  1. Impersonation
  2. Delegate access

Impersonation requires a user who has a special role assignment to be able to access all mailboxes of the organization acting as the user the mailbox belongs to. There is no further permission check. This is, that your code refers to. If the accessing user (A) for example will create a calendar item in a foreign mailbox F on behalf of the use F, the organizer of this calendar item will be F.

When performing delegate access, the accessing user A needs access permission for the foreign mailbox F, but it accesses F acting under it's own identity A. This is what this issue refers to.

You can even combine the two approaches to access a mailbox M, shared with user U using the credentials of the impersonating user I.

Unfortunately the distinguished folder approach doesn't work with delegate access.

from exchangelib.

Takalele avatar Takalele commented on September 25, 2024

@hamarituc

Unfortunately the distinguished folder approach doesn't work with delegate access.

for me it works, i tested contacts with write, read and delete as you can see in the comment i mention above:

#1254 (comment)

from exchangelib.

ecederstrand avatar ecederstrand commented on September 25, 2024

@baloo66 Your bug-test-ok.log ends with a stack trace right when it gets interesting:

Traceback (most recent call last):
  File "C:\workit\Python\cert-tracking\bug-test.py", line 22, in <module>
    print(folder.tree())
  File "C:\Users\userid\AppData\Local\Programs\Python\Python310\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 13-15: character maps to <undefined>
DEBUG:exchangelib.protocol:Server the.exchange.server.url: Closing sessions

Can you provide a new log file from a successful run?

from exchangelib.

ecederstrand avatar ecederstrand commented on September 25, 2024

I'd still like to fix this, but I'll need the requested debug info from someone, or access to a server with delegate access between two accounts.

from exchangelib.

platinops avatar platinops commented on September 25, 2024

Hi Erik,

See logs below - hope this may help somehow.

exchangelib_5.0.3_20240105-125334.log

[email protected] 1492 AAMkADA4MDI2MzFlLTE3NWQtNGVmOC1iNDdmLWY1MmFiZTliZWQzNgBGAAAAAABG0Gu6gfdVTbF/Y4esqfBfBwA3JihwWhSiRZcyeq/ZL3eiAAAAieCyAACm7+ifw6dbS7o9J46MA/UVAASImNK6AAA=
2024-01-05 13:53:34.955 | DEBUG    | productiontools                          | test_exchangelib     | 
[email protected] 3 AAMkADEzNTdmN2NhLWU1YmMtNGU2OC1hYjA3LTVjMjg1OTIwYzFkMwBGAAAAAADH8dnHbvUTQZmIv1CeJwjkBwBBqX592Au9R7r5jZ1twiMIAAAAkZZBAABOq58edH4mToxueqYeGIkxAAT7XX4/AAA=

exchangelib_5.1.0_20240105-125402.log

[email protected] 1492 AAMkADA4MDI2MzFlLTE3NWQtNGVmOC1iNDdmLWY1MmFiZTliZWQzNgBGAAAAAABG0Gu6gfdVTbF/Y4esqfBfBwA3JihwWhSiRZcyeq/ZL3eiAAAAieCyAACm7+ifw6dbS7o9J46MA/UVAASImNK6AAA=
2024-01-05 13:54:03.718 | DEBUG    | productiontools                          | test_exchangelib     | 
[email protected] 1492 AAMkADA4MDI2MzFlLTE3NWQtNGVmOC1iNDdmLWY1MmFiZTliZWQzNgBGAAAAAABG0Gu6gfdVTbF/Y4esqfBfBwA3JihwWhSiRZcyeq/ZL3eiAAAAieCyAACm7+ifw6dbS7o9J46MA/UVAASImNK6AAA=

Code I ran:

import exchangelib as el
import logging

DATETIME_FORMAT = "%Y%m%d-%H%M%S"
file_path = f"exchangelib_{el.__version__}_{dt.datetime.utcnow().strftime(DATETIME_FORMAT)}.log"
file_handler = logging.FileHandler(file_path)
# xml_handler = el.util.PrettyXmlHandler()
logging.basicConfig(level=logging.DEBUG, handlers=[file_handler])
logging.getLogger().setLevel(logging.DEBUG)

credentials = el.Credentials(username=username, password=password)
config = el.Configuration(server=server, credentials=credentials)
for email_address in [email_address_personal, email_address_shared]:
    logger.debug(f"========={email_address}=========")
    account = el.Account(
        primary_smtp_address=email_address,
        autodiscover=False,
        config=config,
        access_type=el.DELEGATE,
    )

    print(
        account.primary_smtp_address,
        account.calendar.all().count(),
        account.calendar.all().order_by("-start")[0].id,
    )

with open(file_path, "r") as file:
    text = file.read()
    text = text.replace(email_address_personal, "[email protected]")
    text = text.replace(email_address_shared, "[email protected]")
    text = text.replace(domain, "domain.com")
with open(file_path, "w") as file:
    file.write(text)

from exchangelib.

lerome avatar lerome commented on September 25, 2024

Yes it solves the issue 👍 (for me at least). Thanks a lot !

from exchangelib.

fswr-crs avatar fswr-crs commented on September 25, 2024

Yes,I had the same problem with acessing external accounts and this commit also works on our System. 👍

from exchangelib.

platinops avatar platinops commented on September 25, 2024

Also fixed here, thanks!

from exchangelib.

ecederstrand avatar ecederstrand commented on September 25, 2024

Cool! I'm closing the issue and will release a new version in the next days.

from exchangelib.

hamarituc avatar hamarituc commented on September 25, 2024

For me it seems there is still an issue left. Now the target mailbox instead of the account holders mailbox is accessed. So the original issue is resolved. But now I get an ErrorAccessDenied execption.

The following code ...

import exchangelib

creds = exchangelib.Credentials(username = 'username', password = 'password')
config = exchangelib.Configuration(service_endpoint = 'https://server.domain/EWS/Exchange.asmx', credentials = creds, version = exchangelib.Version(build = exchangelib.Build(15, 2, 0, 0)))
account = exchangelib.Account(primary_smtp_address = 'mail@domain', autodiscover = False, config = config, access_type = exchangelib.DELEGATE)
account.identity.upn = 'upn@domain'

list(account.calendar.all())

... yields

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
File ~/virtenv/msxcalendar/lib/python3.11/site-packages/cached_property.py:70, in threaded_cached_property.__get__(self, obj, cls)
     68 try:
     69     # check if the value was computed before the lock was acquired
---> 70     return obj_dict[name]
     72 except KeyError:
     73     # if not, do the calculation and release the lock

KeyError: 'calendar'

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
File ~/virtenv/msxcalendar/lib/python3.11/site-packages/cached_property.py:70, in threaded_cached_property.__get__(self, obj, cls)
     68 try:
     69     # check if the value was computed before the lock was acquired
---> 70     return obj_dict[name]
     72 except KeyError:
     73     # if not, do the calculation and release the lock

KeyError: 'root'

During handling of the above exception, another exception occurred:

ErrorAccessDenied                         Traceback (most recent call last)
Cell In[1], line 9
      6 account = exchangelib.Account(primary_smtp_address = 'mail@domain', autodiscover = False, config = config, access_type = exchangelib.DELEGATE)
      7 account.identity.upn = 'upn@domain'
----> 9 list(account.calendar.all())

File ~/virtenv/msxcalendar/lib/python3.11/site-packages/cached_property.py:74, in threaded_cached_property.__get__(self, obj, cls)
     70     return obj_dict[name]
     72 except KeyError:
     73     # if not, do the calculation and release the lock
---> 74     return obj_dict.setdefault(name, self.func(obj))

File ~/virtenv/msxcalendar/lib/python3.11/site-packages/exchangelib/account.py:254, in Account.calendar(self)
    248 @threaded_cached_property
    249 def calendar(self):
    250     # If the account contains a shared calendar from a different user, that calendar will be in the folder list.
    251     # Attempt not to return one of those. An account may not always have a calendar called "Calendar", but a
    252     # Calendar folder with a localized name instead. Return that, if it's available, but always prefer any
    253     # distinguished folder returned by the server.
--> 254     return self.root.get_default_folder(Calendar)

File ~/virtenv/msxcalendar/lib/python3.11/site-packages/cached_property.py:74, in threaded_cached_property.__get__(self, obj, cls)
     70     return obj_dict[name]
     72 except KeyError:
     73     # if not, do the calculation and release the lock
---> 74     return obj_dict.setdefault(name, self.func(obj))

File ~/virtenv/msxcalendar/lib/python3.11/site-packages/exchangelib/account.py:350, in Account.root(self)
    348 @threaded_cached_property
    349 def root(self):
--> 350     return Root.get_distinguished(account=self)

File ~/virtenv/msxcalendar/lib/python3.11/site-packages/exchangelib/folders/roots.py:113, in RootOfHierarchy.get_distinguished(cls, account)
    111     raise ValueError(f"Class {cls} must have a DISTINGUISHED_FOLDER_ID value")
    112 try:
--> 113     return cls.resolve(
    114         account=account,
    115         folder=DistinguishedFolderId(
    116             id=cls.DISTINGUISHED_FOLDER_ID,
    117             mailbox=Mailbox(email_address=account.primary_smtp_address),
    118         ),
    119     )
    120 except MISSING_FOLDER_ERRORS:
    121     raise ErrorFolderNotFound(f"Could not find distinguished folder {cls.DISTINGUISHED_FOLDER_ID}")

File ~/virtenv/msxcalendar/lib/python3.11/site-packages/exchangelib/folders/base.py:516, in BaseFolder.resolve(cls, account, folder)
    513 @classmethod
    514 def resolve(cls, account, folder):
    515     # Resolve a single folder
--> 516     folders = list(FolderCollection(account=account, folders=[folder]).resolve())
    517     if not folders:
    518         raise ErrorFolderNotFound(f"Could not find folder {folder!r}")

File ~/virtenv/msxcalendar/lib/python3.11/site-packages/exchangelib/folders/collections.py:335, in FolderCollection.resolve(self)
    333 # Fetch all properties for the remaining folders of folder IDs
    334 additional_fields = self.get_folder_fields(target_cls=self._get_target_cls())
--> 335 yield from self.__class__(account=self.account, folders=resolveable_folders).get_folders(
    336     additional_fields=additional_fields
    337 )

File ~/virtenv/msxcalendar/lib/python3.11/site-packages/exchangelib/folders/collections.py:403, in FolderCollection.get_folders(self, additional_fields)
    398 # Add required fields
    399 additional_fields.update(
    400     (FieldPath(field=BaseFolder.get_field_by_fieldname(f)) for f in self.REQUIRED_FOLDER_FIELDS)
    401 )
--> 403 yield from GetFolder(account=self.account).call(
    404     folders=self.folders,
    405     additional_fields=additional_fields,
    406     shape=ID_ONLY,
    407 )

File ~/virtenv/msxcalendar/lib/python3.11/site-packages/exchangelib/services/get_folder.py:43, in GetFolder._elems_to_objs(self, elems)
     42 def _elems_to_objs(self, elems):
---> 43     for folder, elem in zip(self.folders, elems):
     44         if isinstance(elem, Exception):
     45             yield elem

File ~/virtenv/msxcalendar/lib/python3.11/site-packages/exchangelib/services/common.py:287, in EWSService._chunked_get_elements(self, payload_func, items, **kwargs)
    285 for i, chunk in enumerate(chunkify(filtered_items, self.chunk_size), start=1):
    286     log.debug("Processing chunk %s containing %s items", i, len(chunk))
--> 287     yield from self._get_elements(payload=payload_func(chunk, **kwargs))

File ~/virtenv/msxcalendar/lib/python3.11/site-packages/exchangelib/services/common.py:308, in EWSService._get_elements(self, payload)
    304 while True:
    305     try:
    306         # Create a generator over the response elements so exceptions in response elements are also raised
    307         # here and can be handled.
--> 308         yield from self._response_generator(payload=payload)
    309         # TODO: Restore session pool size on succeeding request?
    310         return

File ~/virtenv/msxcalendar/lib/python3.11/site-packages/exchangelib/services/common.py:684, in EWSService._get_elements_in_response(self, response)
    659 """Take a list of 'SomeServiceResponseMessage' elements and return the elements in each response message that
    660 we want the service to return. With e.g. 'CreateItem', we get a list of 'CreateItemResponseMessage' elements
    661 and return the 'Message' elements.
   (...)
    681 :return: a generator of items as returned by '_get_elements_in_container()
    682 """
    683 for msg in response:
--> 684     container_or_exc = self._get_element_container(message=msg, name=self.element_container_name)
    685     if isinstance(container_or_exc, (bool, Exception)):
    686         yield container_or_exc

File ~/virtenv/msxcalendar/lib/python3.11/site-packages/exchangelib/services/common.py:606, in EWSService._get_element_container(self, message, name)
    604 # response_class == 'Error', or 'Success' and not 'NoError'
    605 try:
--> 606     raise self._get_exception(code=response_code, text=msg_text, msg_xml=msg_xml)
    607 except self.ERRORS_TO_CATCH_IN_RESPONSE as e:
    608     return e

ErrorAccessDenied: Der Zugriff wird verweigert. Überprüfen Sie die Anmeldeinformationen, und versuchen Sie es dann erneut., Der zugrunde liegende MAPI-Stream hat eine Ausnahme ausgelöst

The user has permission to the calendar folder of the mailbox, but not to the root folder. For some reason the code tries to access the root folder (which is not necessary) and fails there. In 5.0.0 it worked fine. How can I help debugging this issue?

from exchangelib.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.