Skip to content

Commit 2e98960

Browse files
author
Jonathan Holvey
committed
Merge branch 'release-1.3.0'
2 parents ffe4f68 + 7891632 commit 2e98960

File tree

2 files changed

+28
-11
lines changed

2 files changed

+28
-11
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ You will be prompted to enter your username and password, which are used to requ
2121

2222
A username and password can also be provided as arguments of the `connect` function, if prompts are not desirable.
2323

24+
The default authentication URL is `login.microsoftonline.com`. If another top level domain is required for a region-specific account, it can be specified using the `auth_tld` argument.
25+
2426
## Make an API call:
2527

2628
```python
@@ -70,7 +72,7 @@ The default file name for saving and loading sessions is `sp-session.pkl`, howev
7072

7173
## Licence
7274

73-
This software is distributed under the GNU General Public License v3. Copyright 2016-2017 Jonathan Holvey.
75+
This software is distributed under the GNU General Public License v3. Copyright 2016-2018 Jonathan Holvey.
7476

7577
## Credits
7678

session.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010
# XML namespace URLs
1111
ns = {
1212
"wsse": "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
13-
"d": "http://schemas.microsoft.com/ado/2007/08/dataservices"
13+
"psf": "http://schemas.microsoft.com/Passport/SoapServices/SOAPFault",
14+
"d": "http://schemas.microsoft.com/ado/2007/08/dataservices",
15+
"S": "http://www.w3.org/2003/05/soap-envelope"
1416
}
1517

1618

17-
def connect(site, username=None, password=None):
18-
return SharePointSession(site, username, password)
19+
def connect(site, username=None, password=None, auth_tld=None):
20+
return SharePointSession(site, username, password, auth_tld)
1921

2022

2123
def load(filename="sp-session.pkl"):
@@ -45,11 +47,12 @@ class SharePointSession(requests.Session):
4547
<Response [200]>
4648
"""
4749

48-
def __init__(self, site=None, username=None, password=None):
50+
def __init__(self, site=None, username=None, password=None, auth_tld=None):
4951
super().__init__()
5052

5153
if site is not None:
5254
self.site = re.sub(r"^https?://", "", site)
55+
self.auth_tld = auth_tld or "com"
5356
self.expire = datetime.now()
5457
# Request credentials from user
5558
self.username = username or input("Enter your username: ")
@@ -76,19 +79,31 @@ def _spauth(self):
7679

7780
# Request security token from Microsoft Online
7881
print("Requesting security token...\r", end="")
79-
response = requests.post("https://login.microsoftonline.com/extSTS.srf", data=saml)
82+
auth_domain = "login.microsoftonline." + self.auth_tld
83+
try:
84+
response = requests.post("https://{}/extSTS.srf".format(auth_domain), data=saml)
85+
except requests.exceptions.ConnectionError:
86+
print("Could not connect to", auth_domain)
87+
return
8088
# Parse and extract token from returned XML
8189
try:
8290
root = et.fromstring(response.text)
83-
token = root.find(".//wsse:BinarySecurityToken", ns).text
84-
except:
85-
print("Token request failed. Check your username and password")
91+
except et.ParseError:
92+
print("Token request failed. The server did not send a valid response")
93+
return
94+
95+
# Extract token from returned XML
96+
token = root.find(".//wsse:BinarySecurityToken", ns)
97+
# Check for errors and print error messages
98+
if token is None or root.find(".//S:Fault", ns) is not None:
99+
print("{}: {}".format(root.find(".//S:Text", ns).text,
100+
root.find(".//psf:text", ns).text).strip().strip("."))
86101
return
87102

88103
# Request access token from sharepoint site
89104
print("Requesting access cookie... \r", end="")
90105
response = requests.post("https://" + self.site + "/_forms/default.aspx?wa=wsignin1.0",
91-
data=token, headers={"Host": self.site})
106+
data=token.text, headers={"Host": self.site})
92107

93108
# Create access cookie from returned headers
94109
cookie = self._buildcookie(response.cookies)
@@ -139,7 +154,7 @@ def post(self, url, *args, **kwargs):
139154
def getfile(self, url, *args, **kwargs):
140155
"""Stream download of specified URL and output to file"""
141156
# Extract file name from request URL if not provided as keyword argument
142-
filename = kwargs.pop("filename", re.search("[^\/]+$", url).group(0))
157+
filename = kwargs.pop("filename", re.search(r"[^/]+$", url).group(0))
143158
kwargs["stream"] = True
144159
# Request file in stream mode
145160
response = self.get(url, *args, **kwargs)

0 commit comments

Comments
 (0)