OmniSciDB  72c90bc290
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
_samlutils.py
Go to the documentation of this file.
1 import re
2 import requests
3 from html import unescape
4 from urllib.parse import urlparse
5 
6 
8  idpurl,
9  username,
10  password,
11  userformfield,
12  passwordformfield,
13  sslverify=True,
14 ):
15  """
16  Obtains the SAML response from an Identity Provider
17  given the provided username and password.
18 
19  Parameters
20  ----------
21  idpurl : str
22  The logon page of the SAML Identity Provider
23  username : str
24  SAML Username
25  password : str
26  SAML Password
27  userformfield : str
28  The HTML form ID for the username
29  passwordformfield : str
30  The HTML form ID for the password
31  sslverify : bool, optional
32  Verify TLS certificates, by default True
33  """
34 
35  session = requests.Session()
36 
37  response = session.get(idpurl, verify=sslverify)
38  initialurl = response.url
39  formaction = initialurl
40  # print(page.content)
41 
42  # Determine if there's an action in the form, if there is,
43  # use it instead of the page URL
44  asearch = re.search(
45  r'<form\s+.*?\s+action' r'\s*=\s*\"(.*?)\".*?<\s*/form>',
46  response.text,
47  re.IGNORECASE | re.DOTALL,
48  )
49 
50  if asearch:
51  formaction = asearch.group(1)
52 
53  # If the action is a path not a URL, build the full
54  if not formaction.lower().startswith('http'):
55  parsedurl = urlparse(idpurl)
56  formaction = parsedurl.scheme + "://" + parsedurl.netloc + formaction
57 
58  # Un-urlencode the URL
59  formaction = unescape(formaction)
60 
61  formpayload = {userformfield: username, passwordformfield: password}
62 
63  response = session.post(formaction, data=formpayload, verify=sslverify)
64 
65  samlresponse = None
66  ssearch = re.search(
67  r'<input\s+.*?\s+name\s*=\s*'
68  r'\"SAMLResponse\".*?\s+value=\"(.*?)\".*?\/>',
69  response.text,
70  re.IGNORECASE | re.DOTALL,
71  )
72  if ssearch:
73  samlresponse = ssearch.group(1)
74  # Remove any whitespace, some providers include
75  # new lines in the response (!)
76  re.sub(r"[\r\n\t\s]*", "", samlresponse)
77 
78  if not samlresponse:
79  raise ValueError('No SAMLResponse found in response.')
80 
81  return samlresponse