@backtomyfuture/exchange-cli-darwin-arm64 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/_internal/Python +0 -0
- package/bin/_internal/Python.framework/Python +0 -0
- package/bin/_internal/Python.framework/Resources/Info.plist +3 -3
- package/bin/_internal/Python.framework/Versions/3.12/Python +0 -0
- package/bin/_internal/Python.framework/Versions/{3.14 → 3.12}/Resources/Info.plist +3 -3
- package/bin/_internal/Python.framework/Versions/Current/Python +0 -0
- package/bin/_internal/Python.framework/Versions/Current/Resources/Info.plist +3 -3
- package/bin/_internal/_cffi_backend.cpython-312-darwin.so +0 -0
- package/bin/_internal/ada92cb5d92a588d1b93__mypyc.cpython-312-darwin.so +0 -0
- package/bin/_internal/base_library.zip +0 -0
- package/bin/_internal/certifi/cacert.pem +0 -631
- package/bin/_internal/charset_normalizer/{md.cpython-314-darwin.so → cd.cpython-312-darwin.so} +0 -0
- package/bin/_internal/charset_normalizer/{cd.cpython-314-darwin.so → md.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{click-8.3.2.dist-info → click-8.4.2.dist-info}/METADATA +1 -1
- package/bin/_internal/click-8.4.2.dist-info/RECORD +40 -0
- package/bin/_internal/cryptography/hazmat/bindings/_rust.abi3.so +0 -0
- package/bin/_internal/{cryptography-46.0.7.dist-info → cryptography-48.0.1.dist-info}/METADATA +7 -36
- package/bin/_internal/{cryptography-46.0.7.dist-info → cryptography-48.0.1.dist-info}/RECORD +137 -122
- package/bin/_internal/{cryptography-46.0.7.dist-info → cryptography-48.0.1.dist-info}/WHEEL +1 -1
- package/bin/_internal/cryptography-48.0.1.dist-info/sboms/cryptography-rust.cyclonedx.json +1362 -0
- package/bin/_internal/cryptography-48.0.1.dist-info/sboms/sbom.json +43 -0
- package/bin/_internal/exchangelib/__init__.py +120 -0
- package/bin/_internal/exchangelib/account.py +896 -0
- package/bin/_internal/exchangelib/attachments.py +268 -0
- package/bin/_internal/exchangelib/autodiscover/__init__.py +24 -0
- package/bin/_internal/exchangelib/autodiscover/cache.py +150 -0
- package/bin/_internal/exchangelib/autodiscover/discovery.py +491 -0
- package/bin/_internal/exchangelib/autodiscover/protocol.py +58 -0
- package/bin/_internal/exchangelib/configuration.py +106 -0
- package/bin/_internal/exchangelib/credentials.py +319 -0
- package/bin/_internal/exchangelib/errors.py +1710 -0
- package/bin/_internal/exchangelib/ewsdatetime.py +309 -0
- package/bin/_internal/exchangelib/extended_properties.py +311 -0
- package/bin/_internal/exchangelib/fields.py +1842 -0
- package/bin/_internal/exchangelib/folders/__init__.py +249 -0
- package/bin/_internal/exchangelib/folders/base.py +954 -0
- package/bin/_internal/exchangelib/folders/collections.py +576 -0
- package/bin/_internal/exchangelib/folders/known_folders.py +856 -0
- package/bin/_internal/exchangelib/folders/queryset.py +187 -0
- package/bin/_internal/exchangelib/folders/roots.py +390 -0
- package/bin/_internal/exchangelib/indexed_properties.py +96 -0
- package/bin/_internal/exchangelib/items/__init__.py +147 -0
- package/bin/_internal/exchangelib/items/base.py +241 -0
- package/bin/_internal/exchangelib/items/calendar_item.py +466 -0
- package/bin/_internal/exchangelib/items/contact.py +263 -0
- package/bin/_internal/exchangelib/items/item.py +413 -0
- package/bin/_internal/exchangelib/items/message.py +201 -0
- package/bin/_internal/exchangelib/items/post.py +38 -0
- package/bin/_internal/exchangelib/items/task.py +139 -0
- package/bin/_internal/exchangelib/properties.py +2364 -0
- package/bin/_internal/exchangelib/protocol.py +823 -0
- package/bin/_internal/exchangelib/queryset.py +691 -0
- package/bin/_internal/exchangelib/recurrence.py +349 -0
- package/bin/_internal/exchangelib/restriction.py +568 -0
- package/bin/_internal/exchangelib/services/__init__.py +117 -0
- package/bin/_internal/exchangelib/services/archive_item.py +33 -0
- package/bin/_internal/exchangelib/services/common.py +983 -0
- package/bin/_internal/exchangelib/services/convert_id.py +45 -0
- package/bin/_internal/exchangelib/services/copy_item.py +7 -0
- package/bin/_internal/exchangelib/services/create_attachment.py +34 -0
- package/bin/_internal/exchangelib/services/create_folder.py +45 -0
- package/bin/_internal/exchangelib/services/create_item.py +97 -0
- package/bin/_internal/exchangelib/services/create_user_configuration.py +19 -0
- package/bin/_internal/exchangelib/services/delete_attachment.py +28 -0
- package/bin/_internal/exchangelib/services/delete_folder.py +21 -0
- package/bin/_internal/exchangelib/services/delete_item.py +51 -0
- package/bin/_internal/exchangelib/services/delete_user_configuration.py +19 -0
- package/bin/_internal/exchangelib/services/empty_folder.py +25 -0
- package/bin/_internal/exchangelib/services/expand_dl.py +21 -0
- package/bin/_internal/exchangelib/services/export_items.py +27 -0
- package/bin/_internal/exchangelib/services/find_folder.py +80 -0
- package/bin/_internal/exchangelib/services/find_item.py +112 -0
- package/bin/_internal/exchangelib/services/find_people.py +106 -0
- package/bin/_internal/exchangelib/services/get_attachment.py +117 -0
- package/bin/_internal/exchangelib/services/get_delegate.py +45 -0
- package/bin/_internal/exchangelib/services/get_events.py +39 -0
- package/bin/_internal/exchangelib/services/get_folder.py +65 -0
- package/bin/_internal/exchangelib/services/get_item.py +41 -0
- package/bin/_internal/exchangelib/services/get_mail_tips.py +43 -0
- package/bin/_internal/exchangelib/services/get_persona.py +31 -0
- package/bin/_internal/exchangelib/services/get_room_lists.py +21 -0
- package/bin/_internal/exchangelib/services/get_rooms.py +21 -0
- package/bin/_internal/exchangelib/services/get_searchable_mailboxes.py +48 -0
- package/bin/_internal/exchangelib/services/get_server_time_zones.py +39 -0
- package/bin/_internal/exchangelib/services/get_streaming_events.py +102 -0
- package/bin/_internal/exchangelib/services/get_user_availability.py +67 -0
- package/bin/_internal/exchangelib/services/get_user_configuration.py +43 -0
- package/bin/_internal/exchangelib/services/get_user_oof_settings.py +40 -0
- package/bin/_internal/exchangelib/services/get_user_settings.py +87 -0
- package/bin/_internal/exchangelib/services/inbox_rules.py +104 -0
- package/bin/_internal/exchangelib/services/mark_as_junk.py +27 -0
- package/bin/_internal/exchangelib/services/move_folder.py +27 -0
- package/bin/_internal/exchangelib/services/move_item.py +28 -0
- package/bin/_internal/exchangelib/services/resolve_names.py +104 -0
- package/bin/_internal/exchangelib/services/send_item.py +26 -0
- package/bin/_internal/exchangelib/services/send_notification.py +43 -0
- package/bin/_internal/exchangelib/services/set_user_oof_settings.py +34 -0
- package/bin/_internal/exchangelib/services/subscribe.py +125 -0
- package/bin/_internal/exchangelib/services/sync_folder_hierarchy.py +95 -0
- package/bin/_internal/exchangelib/services/sync_folder_items.py +77 -0
- package/bin/_internal/exchangelib/services/unsubscribe.py +21 -0
- package/bin/_internal/exchangelib/services/update_folder.py +158 -0
- package/bin/_internal/exchangelib/services/update_item.py +113 -0
- package/bin/_internal/exchangelib/services/update_user_configuration.py +17 -0
- package/bin/_internal/exchangelib/services/upload_items.py +47 -0
- package/bin/_internal/exchangelib/settings.py +88 -0
- package/bin/_internal/exchangelib/transport.py +214 -0
- package/bin/_internal/exchangelib/util.py +894 -0
- package/bin/_internal/exchangelib/version.py +320 -0
- package/bin/_internal/exchangelib/winzone.py +662 -0
- package/bin/_internal/exchangelib-5.6.0.dist-info/INSTALLER +1 -0
- package/bin/_internal/exchangelib-5.6.0.dist-info/METADATA +77 -0
- package/bin/_internal/exchangelib-5.6.0.dist-info/RECORD +184 -0
- package/bin/_internal/exchangelib-5.6.0.dist-info/licenses/LICENSE +21 -0
- package/bin/_internal/exchangelib-5.6.0.dist-info/top_level.txt +1 -0
- package/bin/_internal/libcrypto.3.dylib +0 -0
- package/bin/_internal/libssl.3.dylib +0 -0
- package/bin/_internal/lxml/_elementpath.cpython-312-darwin.so +0 -0
- package/bin/_internal/lxml/builder.cpython-312-darwin.so +0 -0
- package/bin/_internal/lxml/{etree.cpython-314-darwin.so → etree.cpython-312-darwin.so} +0 -0
- package/bin/_internal/lxml/html/_difflib.cpython-312-darwin.so +0 -0
- package/bin/_internal/lxml/html/diff.cpython-312-darwin.so +0 -0
- package/bin/_internal/lxml/{objectify.cpython-314-darwin.so → objectify.cpython-312-darwin.so} +0 -0
- package/bin/_internal/lxml/sax.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/_asyncio.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/termios.cpython-314-darwin.so → python3.12/lib-dynload/_bisect.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_sha2.cpython-314-darwin.so → python3.12/lib-dynload/_blake2.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_bz2.cpython-314-darwin.so → python3.12/lib-dynload/_bz2.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_codecs_cn.cpython-314-darwin.so → python3.12/lib-dynload/_codecs_cn.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_codecs_hk.cpython-314-darwin.so → python3.12/lib-dynload/_codecs_hk.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_interpqueues.cpython-314-darwin.so → python3.12/lib-dynload/_codecs_iso2022.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_codecs_jp.cpython-314-darwin.so → python3.12/lib-dynload/_codecs_jp.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_codecs_kr.cpython-314-darwin.so → python3.12/lib-dynload/_codecs_kr.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_codecs_tw.cpython-314-darwin.so → python3.12/lib-dynload/_codecs_tw.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_statistics.cpython-314-darwin.so → python3.12/lib-dynload/_contextvars.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_csv.cpython-314-darwin.so → python3.12/lib-dynload/_csv.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/_ctypes.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/_datetime.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_dbm.cpython-314-darwin.so → python3.12/lib-dynload/_dbm.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/_decimal.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/_elementtree.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/_hashlib.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_heapq.cpython-314-darwin.so → python3.12/lib-dynload/_heapq.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/_json.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/_lzma.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_md5.cpython-314-darwin.so → python3.12/lib-dynload/_md5.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/_multibytecodec.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_multiprocessing.cpython-314-darwin.so → python3.12/lib-dynload/_multiprocessing.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/_opcode.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/_pickle.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_bisect.cpython-314-darwin.so → python3.12/lib-dynload/_posixshmem.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_posixsubprocess.cpython-314-darwin.so → python3.12/lib-dynload/_posixsubprocess.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_queue.cpython-314-darwin.so → python3.12/lib-dynload/_queue.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_random.cpython-314-darwin.so → python3.12/lib-dynload/_random.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_scproxy.cpython-314-darwin.so → python3.12/lib-dynload/_scproxy.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_sha1.cpython-314-darwin.so → python3.12/lib-dynload/_sha1.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/_sha2.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_blake2.cpython-314-darwin.so → python3.12/lib-dynload/_sha3.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/_socket.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/_ssl.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_posixshmem.cpython-314-darwin.so → python3.12/lib-dynload/_statistics.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/_struct.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_uuid.cpython-314-darwin.so → python3.12/lib-dynload/_uuid.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_zoneinfo.cpython-314-darwin.so → python3.12/lib-dynload/_zoneinfo.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/array.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/binascii.cpython-314-darwin.so → python3.12/lib-dynload/binascii.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/fcntl.cpython-314-darwin.so → python3.12/lib-dynload/fcntl.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/grp.cpython-314-darwin.so → python3.12/lib-dynload/grp.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/math.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/_sha3.cpython-314-darwin.so → python3.12/lib-dynload/mmap.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/pyexpat.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/readline.cpython-312-darwin.so +0 -0
- package/bin/_internal/{python3.14/lib-dynload/resource.cpython-314-darwin.so → python3.12/lib-dynload/resource.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/select.cpython-314-darwin.so → python3.12/lib-dynload/select.cpython-312-darwin.so} +0 -0
- package/bin/_internal/{python3.14/lib-dynload/syslog.cpython-314-darwin.so → python3.12/lib-dynload/syslog.cpython-312-darwin.so} +0 -0
- package/bin/_internal/python3.12/lib-dynload/termios.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/unicodedata.cpython-312-darwin.so +0 -0
- package/bin/_internal/python3.12/lib-dynload/zlib.cpython-312-darwin.so +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/Casablanca +0 -0
- package/bin/_internal/tzdata/zoneinfo/Africa/El_Aaiun +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Edmonton +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Vancouver +0 -0
- package/bin/_internal/tzdata/zoneinfo/America/Yellowknife +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Ho_Chi_Minh +0 -0
- package/bin/_internal/tzdata/zoneinfo/Asia/Saigon +0 -0
- package/bin/_internal/tzdata/zoneinfo/Canada/Mountain +0 -0
- package/bin/_internal/tzdata/zoneinfo/Canada/Pacific +0 -0
- package/bin/_internal/tzdata/zoneinfo/leapseconds +4 -4
- package/bin/_internal/tzdata/zoneinfo/tzdata.zi +11 -131
- package/bin/_internal/tzdata/zoneinfo/zone.tab +2 -2
- package/bin/_internal/tzdata/zoneinfo/zone1970.tab +2 -2
- package/bin/_internal/tzdata/zoneinfo/zonenow.tab +8 -2
- package/bin/exchange-cli +0 -0
- package/package.json +10 -7
- package/bin/_internal/81d243bd2c585b0f4821__mypyc.cpython-314-darwin.so +0 -0
- package/bin/_internal/Python.framework/Versions/3.14/Python +0 -0
- package/bin/_internal/_cffi_backend.cpython-314-darwin.so +0 -0
- package/bin/_internal/click-8.3.2.dist-info/RECORD +0 -40
- package/bin/_internal/liblzma.5.dylib +0 -0
- package/bin/_internal/libmpdec.4.dylib +0 -0
- package/bin/_internal/libzstd.1.dylib +0 -0
- package/bin/_internal/lxml/_elementpath.cpython-314-darwin.so +0 -0
- package/bin/_internal/lxml/builder.cpython-314-darwin.so +0 -0
- package/bin/_internal/lxml/html/_difflib.cpython-314-darwin.so +0 -0
- package/bin/_internal/lxml/html/diff.cpython-314-darwin.so +0 -0
- package/bin/_internal/lxml/sax.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_asyncio.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_codecs_iso2022.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_ctypes.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_decimal.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_elementtree.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_hashlib.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_hmac.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_interpreters.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_json.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_lzma.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_multibytecodec.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_pickle.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_socket.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_ssl.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_struct.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/_zstd.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/array.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/math.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/mmap.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/pyexpat.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/readline.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/unicodedata.cpython-314-darwin.so +0 -0
- package/bin/_internal/python3.14/lib-dynload/zlib.cpython-314-darwin.so +0 -0
- package/bin/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/INSTALLER +0 -1
- package/bin/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/METADATA +0 -133
- package/bin/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/RECORD +0 -21
- package/bin/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/REQUESTED +0 -0
- package/bin/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/licenses/LICENSE +0 -73
- package/bin/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/top_level.txt +0 -1
- /package/bin/_internal/{click-8.3.2.dist-info → click-8.4.2.dist-info}/INSTALLER +0 -0
- /package/bin/_internal/{click-8.3.2.dist-info → click-8.4.2.dist-info}/WHEEL +0 -0
- /package/bin/_internal/{click-8.3.2.dist-info → click-8.4.2.dist-info}/licenses/LICENSE.txt +0 -0
- /package/bin/_internal/{cryptography-46.0.7.dist-info → cryptography-48.0.1.dist-info}/INSTALLER +0 -0
- /package/bin/_internal/{cryptography-46.0.7.dist-info → cryptography-48.0.1.dist-info}/licenses/LICENSE +0 -0
- /package/bin/_internal/{cryptography-46.0.7.dist-info → cryptography-48.0.1.dist-info}/licenses/LICENSE.APACHE +0 -0
- /package/bin/_internal/{cryptography-46.0.7.dist-info → cryptography-48.0.1.dist-info}/licenses/LICENSE.BSD +0 -0
- /package/bin/_internal/{setuptools/_vendor/importlib_metadata-8.7.1.dist-info → exchangelib-5.6.0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from ..util import create_element, set_xml_value
|
|
2
|
+
from .common import EWSAccountService
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class UpdateUserConfiguration(EWSAccountService):
|
|
6
|
+
"""MSDN:
|
|
7
|
+
https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/updateuserconfiguration-operation
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
SERVICE_NAME = "UpdateUserConfiguration"
|
|
11
|
+
returns_elements = False
|
|
12
|
+
|
|
13
|
+
def call(self, user_configuration):
|
|
14
|
+
return self._get_elements(payload=self.get_payload(user_configuration=user_configuration))
|
|
15
|
+
|
|
16
|
+
def get_payload(self, user_configuration):
|
|
17
|
+
return set_xml_value(create_element(f"m:{self.SERVICE_NAME}"), user_configuration, version=self.account.version)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from ..properties import ItemId, ParentFolderId
|
|
2
|
+
from ..util import MNS, add_xml_child, create_element, set_xml_value
|
|
3
|
+
from .common import EWSAccountService, to_item_id
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class UploadItems(EWSAccountService):
|
|
7
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/uploaditems-operation"""
|
|
8
|
+
|
|
9
|
+
SERVICE_NAME = "UploadItems"
|
|
10
|
+
element_container_name = f"{{{MNS}}}ItemId"
|
|
11
|
+
|
|
12
|
+
def call(self, items):
|
|
13
|
+
# _pool_requests expects 'items', not 'data'
|
|
14
|
+
return self._elems_to_objs(self._chunked_get_elements(self.get_payload, items=items))
|
|
15
|
+
|
|
16
|
+
def get_payload(self, items):
|
|
17
|
+
"""Upload given items to given account.
|
|
18
|
+
|
|
19
|
+
'items' is an iterable of tuples where the first element is a Folder instance representing the ParentFolder
|
|
20
|
+
that the item will be placed in and the second element is a tuple containing an optional ItemId, an optional
|
|
21
|
+
Item.is_associated boolean, and a Data string returned from an ExportItems.
|
|
22
|
+
call.
|
|
23
|
+
|
|
24
|
+
:param items:
|
|
25
|
+
"""
|
|
26
|
+
payload = create_element(f"m:{self.SERVICE_NAME}")
|
|
27
|
+
items_elem = create_element("m:Items")
|
|
28
|
+
payload.append(items_elem)
|
|
29
|
+
for parent_folder, (item_id, is_associated, data_str) in items:
|
|
30
|
+
# TODO: The full spec also allows the "UpdateOrCreate" create action.
|
|
31
|
+
attrs = dict(CreateAction="Update" if item_id else "CreateNew")
|
|
32
|
+
if is_associated is not None:
|
|
33
|
+
attrs["IsAssociated"] = is_associated
|
|
34
|
+
item = create_element("t:Item", attrs=attrs)
|
|
35
|
+
set_xml_value(item, ParentFolderId(parent_folder.id, parent_folder.changekey), version=self.account.version)
|
|
36
|
+
if item_id:
|
|
37
|
+
set_xml_value(item, to_item_id(item_id, ItemId), version=self.account.version)
|
|
38
|
+
add_xml_child(item, "t:Data", data_str)
|
|
39
|
+
items_elem.append(item)
|
|
40
|
+
return payload
|
|
41
|
+
|
|
42
|
+
def _elem_to_obj(self, elem):
|
|
43
|
+
return elem.get(ItemId.ID_ATTR), elem.get(ItemId.CHANGEKEY_ATTR)
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def _get_elements_in_container(cls, container):
|
|
47
|
+
return [container]
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
|
|
3
|
+
from .ewsdatetime import UTC
|
|
4
|
+
from .fields import Choice, ChoiceField, DateTimeField, MessageField
|
|
5
|
+
from .properties import EWSElement, OutOfOffice
|
|
6
|
+
from .util import create_element, set_xml_value
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class OofSettings(EWSElement):
|
|
10
|
+
"""MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/oofsettings"""
|
|
11
|
+
|
|
12
|
+
ELEMENT_NAME = "OofSettings"
|
|
13
|
+
REQUEST_ELEMENT_NAME = "UserOofSettings"
|
|
14
|
+
|
|
15
|
+
ENABLED = "Enabled"
|
|
16
|
+
SCHEDULED = "Scheduled"
|
|
17
|
+
DISABLED = "Disabled"
|
|
18
|
+
STATE_CHOICES = (ENABLED, SCHEDULED, DISABLED)
|
|
19
|
+
|
|
20
|
+
state = ChoiceField(field_uri="OofState", is_required=True, choices={Choice(c) for c in STATE_CHOICES})
|
|
21
|
+
external_audience = ChoiceField(
|
|
22
|
+
field_uri="ExternalAudience", choices={Choice("None"), Choice("Known"), Choice("All")}, default="All"
|
|
23
|
+
)
|
|
24
|
+
start = DateTimeField(field_uri="StartTime")
|
|
25
|
+
end = DateTimeField(field_uri="EndTime")
|
|
26
|
+
internal_reply = MessageField(field_uri="InternalReply")
|
|
27
|
+
external_reply = MessageField(field_uri="ExternalReply")
|
|
28
|
+
|
|
29
|
+
def clean(self, version=None):
|
|
30
|
+
super().clean(version=version)
|
|
31
|
+
if self.state == self.SCHEDULED:
|
|
32
|
+
if not self.start or not self.end:
|
|
33
|
+
raise ValueError(f"'start' and 'end' must be set when state is {self.SCHEDULED!r}")
|
|
34
|
+
if self.start >= self.end:
|
|
35
|
+
raise ValueError("'start' must be before 'end'")
|
|
36
|
+
if self.end < datetime.datetime.now(tz=UTC):
|
|
37
|
+
raise ValueError("'end' must be in the future")
|
|
38
|
+
# Some servers only like UTC timestamps
|
|
39
|
+
self.start = self.start.astimezone(UTC)
|
|
40
|
+
self.end = self.end.astimezone(UTC)
|
|
41
|
+
if self.state != self.DISABLED and (not self.internal_reply or not self.external_reply):
|
|
42
|
+
raise ValueError(f"'internal_reply' and 'external_reply' must be set when state is not {self.DISABLED!r}")
|
|
43
|
+
|
|
44
|
+
@classmethod
|
|
45
|
+
def from_xml(cls, elem, account):
|
|
46
|
+
kwargs = {}
|
|
47
|
+
for attr in ("state", "external_audience", "internal_reply", "external_reply"):
|
|
48
|
+
f = cls.get_field_by_fieldname(attr)
|
|
49
|
+
kwargs[attr] = f.from_xml(elem=elem, account=account)
|
|
50
|
+
kwargs.update(OutOfOffice.duration_to_start_end(elem=elem, account=account))
|
|
51
|
+
cls._clear(elem)
|
|
52
|
+
return cls(**kwargs)
|
|
53
|
+
|
|
54
|
+
def to_xml(self, version):
|
|
55
|
+
self.clean(version=version)
|
|
56
|
+
elem = create_element(f"t:{self.REQUEST_ELEMENT_NAME}")
|
|
57
|
+
for attr in ("state", "external_audience"):
|
|
58
|
+
value = getattr(self, attr)
|
|
59
|
+
f = self.get_field_by_fieldname(attr)
|
|
60
|
+
set_xml_value(elem, f.to_xml(value, version=version))
|
|
61
|
+
if self.start or self.end:
|
|
62
|
+
duration = create_element("t:Duration")
|
|
63
|
+
if self.start:
|
|
64
|
+
f = self.get_field_by_fieldname("start")
|
|
65
|
+
set_xml_value(duration, f.to_xml(self.start, version=version))
|
|
66
|
+
if self.end:
|
|
67
|
+
f = self.get_field_by_fieldname("end")
|
|
68
|
+
set_xml_value(duration, f.to_xml(self.end, version=version))
|
|
69
|
+
elem.append(duration)
|
|
70
|
+
for attr in ("internal_reply", "external_reply"):
|
|
71
|
+
value = getattr(self, attr)
|
|
72
|
+
if value is None:
|
|
73
|
+
value = "" # The value can be empty, but the XML element must always be present
|
|
74
|
+
f = self.get_field_by_fieldname(attr)
|
|
75
|
+
set_xml_value(elem, f.to_xml(value, version=version))
|
|
76
|
+
return elem
|
|
77
|
+
|
|
78
|
+
def __hash__(self):
|
|
79
|
+
# Customize comparison
|
|
80
|
+
if self.state == self.DISABLED:
|
|
81
|
+
# All values except state are ignored by the server
|
|
82
|
+
relevant_attrs = ("state",)
|
|
83
|
+
elif self.state != self.SCHEDULED:
|
|
84
|
+
# 'start' and 'end' values are ignored by the server, and the server always returns today's date
|
|
85
|
+
relevant_attrs = tuple(f.name for f in self.FIELDS if f.name not in ("start", "end"))
|
|
86
|
+
else:
|
|
87
|
+
relevant_attrs = tuple(f.name for f in self.FIELDS)
|
|
88
|
+
return hash(tuple(getattr(self, attr) for attr in relevant_attrs))
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from contextlib import suppress
|
|
3
|
+
|
|
4
|
+
import requests.auth
|
|
5
|
+
import requests_ntlm
|
|
6
|
+
import requests_oauthlib
|
|
7
|
+
|
|
8
|
+
from .errors import RateLimitError, TransportError, UnauthorizedError
|
|
9
|
+
from .util import CONNECTION_ERRORS, TLS_ERRORS, _back_off_if_needed
|
|
10
|
+
|
|
11
|
+
log = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
# Authentication method enums
|
|
14
|
+
NOAUTH = "no authentication"
|
|
15
|
+
NTLM = "NTLM"
|
|
16
|
+
BASIC = "basic"
|
|
17
|
+
DIGEST = "digest"
|
|
18
|
+
GSSAPI = "gssapi"
|
|
19
|
+
SSPI = "sspi"
|
|
20
|
+
OAUTH2 = "OAuth 2.0"
|
|
21
|
+
CBA = "CBA" # Certificate Based Authentication
|
|
22
|
+
|
|
23
|
+
# The auth types that must be accompanied by a credentials object
|
|
24
|
+
CREDENTIALS_REQUIRED = (NTLM, BASIC, DIGEST, OAUTH2)
|
|
25
|
+
|
|
26
|
+
AUTH_TYPE_MAP = {
|
|
27
|
+
NTLM: requests_ntlm.HttpNtlmAuth,
|
|
28
|
+
BASIC: requests.auth.HTTPBasicAuth,
|
|
29
|
+
DIGEST: requests.auth.HTTPDigestAuth,
|
|
30
|
+
OAUTH2: requests_oauthlib.OAuth2,
|
|
31
|
+
CBA: None,
|
|
32
|
+
NOAUTH: None,
|
|
33
|
+
}
|
|
34
|
+
with suppress(ImportError):
|
|
35
|
+
# Kerberos auth is optional
|
|
36
|
+
import requests_gssapi
|
|
37
|
+
|
|
38
|
+
AUTH_TYPE_MAP[GSSAPI] = requests_gssapi.HTTPSPNEGOAuth
|
|
39
|
+
with suppress(ImportError):
|
|
40
|
+
# SSPI auth is optional
|
|
41
|
+
import requests_negotiate_sspi
|
|
42
|
+
|
|
43
|
+
AUTH_TYPE_MAP[SSPI] = requests_negotiate_sspi.HttpNegotiateAuth
|
|
44
|
+
|
|
45
|
+
DEFAULT_ENCODING = "utf-8"
|
|
46
|
+
DEFAULT_HEADERS = {"Content-Type": f"text/xml; charset={DEFAULT_ENCODING}", "Accept-Encoding": "gzip, deflate"}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def get_auth_instance(auth_type, **kwargs):
|
|
50
|
+
"""Return an *Auth instance suitable for the requests package.
|
|
51
|
+
|
|
52
|
+
:param auth_type:
|
|
53
|
+
:param kwargs:
|
|
54
|
+
"""
|
|
55
|
+
model = AUTH_TYPE_MAP[auth_type]
|
|
56
|
+
if model is None:
|
|
57
|
+
return None
|
|
58
|
+
if auth_type == GSSAPI:
|
|
59
|
+
# Kerberos auth relies on credentials supplied via a ticket available externally to this library
|
|
60
|
+
return model()
|
|
61
|
+
if auth_type == SSPI:
|
|
62
|
+
# SSPI auth does not require credentials, but can have it
|
|
63
|
+
return model(**kwargs)
|
|
64
|
+
return model(**kwargs)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def get_service_authtype(protocol):
|
|
68
|
+
# Get auth type by tasting headers from the server. Only do POST requests. HEAD is too error-prone, and some servers
|
|
69
|
+
# are set up to redirect to OWA on all requests except POST to /EWS/Exchange.asmx
|
|
70
|
+
#
|
|
71
|
+
# We don't know the API version yet, but we need it to create a valid request because some Exchange servers only
|
|
72
|
+
# respond when given a valid request. Try all known versions. Gross.
|
|
73
|
+
from .services import ConvertId
|
|
74
|
+
|
|
75
|
+
service_endpoint = protocol.service_endpoint
|
|
76
|
+
retry_policy = protocol.retry_policy
|
|
77
|
+
wait = protocol.RETRY_WAIT
|
|
78
|
+
for api_version in ConvertId.supported_api_versions():
|
|
79
|
+
protocol.api_version_hint = api_version
|
|
80
|
+
data = protocol.dummy_xml()
|
|
81
|
+
log.debug("Requesting %s from %s", data, service_endpoint)
|
|
82
|
+
while True:
|
|
83
|
+
_back_off_if_needed(retry_policy.back_off_until)
|
|
84
|
+
log.debug("Trying to get service auth type for %s", service_endpoint)
|
|
85
|
+
with protocol.raw_session(service_endpoint) as s:
|
|
86
|
+
try:
|
|
87
|
+
r = s.post(
|
|
88
|
+
url=service_endpoint,
|
|
89
|
+
data=data,
|
|
90
|
+
allow_redirects=False,
|
|
91
|
+
timeout=protocol.TIMEOUT,
|
|
92
|
+
)
|
|
93
|
+
r.close() # Release memory
|
|
94
|
+
break
|
|
95
|
+
except TLS_ERRORS as e:
|
|
96
|
+
# Don't retry on TLS errors. They will most likely be persistent.
|
|
97
|
+
raise TransportError(str(e))
|
|
98
|
+
except CONNECTION_ERRORS as e:
|
|
99
|
+
log.info("Connection error on URL %s.", service_endpoint)
|
|
100
|
+
if not retry_policy.fail_fast:
|
|
101
|
+
retry_policy.back_off(wait)
|
|
102
|
+
continue
|
|
103
|
+
raise TransportError(str(e)) from e
|
|
104
|
+
finally:
|
|
105
|
+
wait *= 2
|
|
106
|
+
if r.status_code not in (200, 401):
|
|
107
|
+
log.debug("Unexpected response: %s %s", r.status_code, r.reason)
|
|
108
|
+
continue
|
|
109
|
+
try:
|
|
110
|
+
auth_type = get_auth_method_from_response(response=r)
|
|
111
|
+
log.debug("Auth type is %s", auth_type)
|
|
112
|
+
return auth_type
|
|
113
|
+
except UnauthorizedError:
|
|
114
|
+
continue
|
|
115
|
+
raise TransportError("Failed to get auth type from service")
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def get_autodiscover_authtype(protocol):
|
|
119
|
+
data = protocol.dummy_xml()
|
|
120
|
+
headers = {"X-AnchorMailbox": "DUMMY@example.com"} # Required in case of OAuth
|
|
121
|
+
r = get_unauthenticated_autodiscover_response(protocol=protocol, method="post", headers=headers, data=data)
|
|
122
|
+
try:
|
|
123
|
+
auth_type = get_auth_method_from_response(response=r)
|
|
124
|
+
log.debug("Auth type is %s", auth_type)
|
|
125
|
+
return auth_type
|
|
126
|
+
except UnauthorizedError:
|
|
127
|
+
raise TransportError("Failed to get autodiscover auth type from service")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def get_unauthenticated_autodiscover_response(protocol, method, headers=None, data=None):
|
|
131
|
+
service_endpoint = protocol.service_endpoint
|
|
132
|
+
retry_policy = protocol.retry_policy
|
|
133
|
+
wait = protocol.RETRY_WAIT
|
|
134
|
+
while True:
|
|
135
|
+
_back_off_if_needed(retry_policy.back_off_until)
|
|
136
|
+
log.debug("Trying to get response from %s", service_endpoint)
|
|
137
|
+
with protocol.raw_session(service_endpoint) as s:
|
|
138
|
+
try:
|
|
139
|
+
r = getattr(s, method)(
|
|
140
|
+
url=service_endpoint,
|
|
141
|
+
headers=headers,
|
|
142
|
+
data=data,
|
|
143
|
+
allow_redirects=False,
|
|
144
|
+
timeout=protocol.TIMEOUT,
|
|
145
|
+
)
|
|
146
|
+
r.close() # Release memory
|
|
147
|
+
break
|
|
148
|
+
except TLS_ERRORS as e:
|
|
149
|
+
# Don't retry on TLS errors. But wrap, so we can catch later and continue with the next endpoint.
|
|
150
|
+
raise TransportError(str(e))
|
|
151
|
+
except CONNECTION_ERRORS as e:
|
|
152
|
+
log.debug("Connection error on URL %s: %s", service_endpoint, e)
|
|
153
|
+
if not retry_policy.fail_fast:
|
|
154
|
+
try:
|
|
155
|
+
retry_policy.back_off(wait)
|
|
156
|
+
continue
|
|
157
|
+
except RateLimitError:
|
|
158
|
+
pass
|
|
159
|
+
raise TransportError(str(e)) from e
|
|
160
|
+
finally:
|
|
161
|
+
wait *= 2
|
|
162
|
+
return r
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def get_auth_method_from_response(response):
|
|
166
|
+
# First, get the auth method from headers. Then, test credentials. Don't handle redirects - burden is on caller.
|
|
167
|
+
log.debug("Request headers: %s", response.request.headers)
|
|
168
|
+
log.debug("Response headers: %s", response.headers)
|
|
169
|
+
if response.status_code == 200:
|
|
170
|
+
return NOAUTH
|
|
171
|
+
# Get auth type from headers
|
|
172
|
+
for key, val in response.headers.items():
|
|
173
|
+
if key.lower() == "www-authenticate":
|
|
174
|
+
# Requests will combine multiple HTTP headers into one in 'request.headers'
|
|
175
|
+
vals = _tokenize(val.lower())
|
|
176
|
+
for v in vals:
|
|
177
|
+
if v.startswith("realm"):
|
|
178
|
+
realm = v.split("=")[1].strip('"')
|
|
179
|
+
log.debug("realm: %s", realm)
|
|
180
|
+
# Prefer most secure auth method if more than one is offered. See discussion at
|
|
181
|
+
# http://docs.oracle.com/javase/7/docs/technotes/guides/net/http-auth.html
|
|
182
|
+
if "digest" in vals:
|
|
183
|
+
return DIGEST
|
|
184
|
+
if "ntlm" in vals:
|
|
185
|
+
return NTLM
|
|
186
|
+
if "basic" in vals:
|
|
187
|
+
return BASIC
|
|
188
|
+
elif key.lower() == "ms-diagnostics-public" and "Modern Auth" in val:
|
|
189
|
+
return OAUTH2
|
|
190
|
+
raise UnauthorizedError("No compatible auth type was reported by server")
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def _tokenize(val):
|
|
194
|
+
# Splits cookie auth values
|
|
195
|
+
auth_methods = []
|
|
196
|
+
auth_method = ""
|
|
197
|
+
quote = False
|
|
198
|
+
for c in val:
|
|
199
|
+
if c in (" ", ",") and not quote:
|
|
200
|
+
if auth_method not in ("", ","):
|
|
201
|
+
auth_methods.append(auth_method)
|
|
202
|
+
auth_method = ""
|
|
203
|
+
continue
|
|
204
|
+
if c == '"':
|
|
205
|
+
auth_method += c
|
|
206
|
+
if quote:
|
|
207
|
+
auth_methods.append(auth_method)
|
|
208
|
+
auth_method = ""
|
|
209
|
+
quote = not quote
|
|
210
|
+
continue
|
|
211
|
+
auth_method += c
|
|
212
|
+
if auth_method:
|
|
213
|
+
auth_methods.append(auth_method)
|
|
214
|
+
return auth_methods
|