Add debugging example to CODE_SAMPLES.md (#295)
Add an example invocation to CODE_SAMPLES that would allow for MITM interception as well as debug prints to the console. Drive-By: blacken the code samples. Drive-By: Make code samples compliant with python3 (print->print()) Fixes: #270
This commit is contained in:
parent
0401299dbb
commit
4075c41ecc
1 changed files with 137 additions and 26 deletions
163
CODE_SAMPLES.md
163
CODE_SAMPLES.md
|
@ -25,56 +25,55 @@ import datetime
|
|||
from pyicloud import PyiCloudService
|
||||
|
||||
|
||||
print('Setup Time Zone')
|
||||
time.strftime('%X %x %Z')
|
||||
os.environ['TZ'] = 'America/New_York'
|
||||
print("Setup Time Zone")
|
||||
time.strftime("%X %x %Z")
|
||||
os.environ["TZ"] = "America/New_York"
|
||||
|
||||
|
||||
|
||||
print('Py iCloud Services')
|
||||
api = PyiCloudService('your@me.com', 'password')
|
||||
print("Py iCloud Services")
|
||||
api = PyiCloudService("your@me.com", "password")
|
||||
|
||||
if api.requires_2fa:
|
||||
print "Two-factor authentication required. Your trusted devices are:"
|
||||
print("Two-factor authentication required. Your trusted devices are:")
|
||||
|
||||
devices = api.trusted_devices
|
||||
for i, device in enumerate(devices):
|
||||
print " %s: %s" % (i, device.get('deviceName', "SMS to %s" %
|
||||
device.get('phoneNumber')))
|
||||
print(
|
||||
" %s: %s"
|
||||
% (i, device.get("deviceName", "SMS to %s" % device.get("phoneNumber")))
|
||||
)
|
||||
|
||||
device = click.prompt('Which device would you like to use?', default=0)
|
||||
device = click.prompt("Which device would you like to use?", default=0)
|
||||
device = devices[device]
|
||||
if not api.send_verification_code(device):
|
||||
print "Failed to send verification code"
|
||||
print("Failed to send verification code")
|
||||
sys.exit(1)
|
||||
|
||||
code = click.prompt('Please enter validation code')
|
||||
code = click.prompt("Please enter validation code")
|
||||
if not api.validate_verification_code(device, code):
|
||||
print "Failed to verify verification code"
|
||||
print("Failed to verify verification code")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
#
|
||||
# Devices
|
||||
#
|
||||
print('Devices')
|
||||
print("Devices")
|
||||
print(api.devices)
|
||||
print(api.devices[0])
|
||||
print(api.iphone)
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Location
|
||||
#
|
||||
print('Location')
|
||||
print("Location")
|
||||
print(api.iphone.location())
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Status
|
||||
#
|
||||
print('Status')
|
||||
print("Status")
|
||||
print(api.iphone.status())
|
||||
|
||||
#
|
||||
|
@ -86,7 +85,7 @@ print(api.iphone.status())
|
|||
#
|
||||
# Events
|
||||
#
|
||||
print('Events')
|
||||
print("Events")
|
||||
print(api.calendar.events())
|
||||
from_dt = datetime.date(2018, 1, 1)
|
||||
to_dt = datetime.date(2018, 1, 31)
|
||||
|
@ -96,17 +95,129 @@ print(api.calendar.events(from_dt, to_dt))
|
|||
# ========
|
||||
# Contacts
|
||||
# ========
|
||||
print('Contacts')
|
||||
print("Contacts")
|
||||
for c in api.contacts.all():
|
||||
print c.get('firstName'), c.get('phones')
|
||||
|
||||
|
||||
print(c.get("firstName"), c.get("phones"))
|
||||
|
||||
|
||||
# =======================
|
||||
# File Storage (Ubiquity)
|
||||
# =======================
|
||||
|
||||
# You can access documents stored in your iCloud account by using the
|
||||
# You can access documents stored in your iCloud account by using the
|
||||
# ``files`` property's ``dir`` method:
|
||||
print('File Storage')
|
||||
print("File Storage")
|
||||
print(api.files.dir())
|
||||
```
|
||||
|
||||
## From [@ixs](https://github.com/ixs)
|
||||
|
||||
### Debug build of pyicloud
|
||||
|
||||
This example allows to use tools like mitmproxy, fiddler, charles or similiar
|
||||
things to debug the data sent on the wire.
|
||||
|
||||
In addition, the underlying requests module and the http.client are asked, to
|
||||
output all data sent and received to stdout.
|
||||
|
||||
This uses code taken from [How do I disable the security certificate check in Python requests](https://stackoverflow.com/questions/15445981/how-do-i-disable-the-security-certificate-check-in-python-requests)
|
||||
and [Log all requests from the python-requests module](https://stackoverflow.com/questions/16337511/log-all-requests-from-the-python-requests-module)
|
||||
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import contextlib
|
||||
import http.client
|
||||
import logging
|
||||
import requests
|
||||
import warnings
|
||||
from pprint import pprint
|
||||
from pyicloud import PyiCloudService
|
||||
from urllib3.exceptions import InsecureRequestWarning
|
||||
|
||||
# Handle certificate warnings by ignoring them
|
||||
old_merge_environment_settings = requests.Session.merge_environment_settings
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def no_ssl_verification():
|
||||
opened_adapters = set()
|
||||
|
||||
def merge_environment_settings(self, url, proxies, stream, verify, cert):
|
||||
# Verification happens only once per connection so we need to close
|
||||
# all the opened adapters once we're done. Otherwise, the effects of
|
||||
# verify=False persist beyond the end of this context manager.
|
||||
opened_adapters.add(self.get_adapter(url))
|
||||
|
||||
settings = old_merge_environment_settings(
|
||||
self, url, proxies, stream, verify, cert
|
||||
)
|
||||
settings["verify"] = False
|
||||
|
||||
return settings
|
||||
|
||||
requests.Session.merge_environment_settings = merge_environment_settings
|
||||
|
||||
try:
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore", InsecureRequestWarning)
|
||||
yield
|
||||
finally:
|
||||
requests.Session.merge_environment_settings = old_merge_environment_settings
|
||||
|
||||
for adapter in opened_adapters:
|
||||
try:
|
||||
adapter.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
# Monkeypatch the http client for full debugging output
|
||||
httpclient_logger = logging.getLogger("http.client")
|
||||
|
||||
|
||||
def httpclient_logging_patch(level=logging.DEBUG):
|
||||
"""Enable HTTPConnection debug logging to the logging framework"""
|
||||
|
||||
def httpclient_log(*args):
|
||||
httpclient_logger.log(level, " ".join(args))
|
||||
|
||||
# mask the print() built-in in the http.client module to use
|
||||
# logging instead
|
||||
http.client.print = httpclient_log
|
||||
# enable debugging
|
||||
http.client.HTTPConnection.debuglevel = 1
|
||||
|
||||
|
||||
# Enable general debug logging
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
httpclient_logging_patch()
|
||||
|
||||
api = PyiCloudService(username, password)
|
||||
if api.requires_2sa:
|
||||
print("Two-factor authentication required. Your trusted devices are:")
|
||||
|
||||
devices = api.trusted_devices
|
||||
for i, device in enumerate(devices):
|
||||
print(
|
||||
" %s: %s"
|
||||
% (i, device.get("deviceName", "SMS to %s") % device.get("phoneNumber"))
|
||||
)
|
||||
|
||||
device = click.prompt("Which device would you like to use?", default=0)
|
||||
device = devices[device]
|
||||
if not api.send_verification_code(device):
|
||||
print("Failed to send verification code")
|
||||
sys.exit(1)
|
||||
|
||||
code = click.prompt("Please enter validation code")
|
||||
if not api.validate_verification_code(device, code):
|
||||
print("Failed to verify verification code")
|
||||
sys.exit(1)
|
||||
|
||||
# This request will not fail, even if using intercepting proxies.
|
||||
with no_ssl_verification():
|
||||
pprint(api.account)
|
||||
```
|
||||
|
|
Loading…
Reference in a new issue