Skip to content

Commit ac56076

Browse files
committed
Close #14 - Fix Typos. Cosmetics
1 parent 20e1460 commit ac56076

6 files changed

Lines changed: 87 additions & 86 deletions

File tree

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,13 @@ in the form of URL string which we use to redirect the user to our identity
8585
provider--OneLogin::
8686

8787
from BaseHTTPServer import BaseHTTPRequestHandler
88-
from onelogin.saml import AuthnRequest
88+
from onelogin.saml import AuthRequest
8989
...
9090
class SampleAppHTTPRequestHandler(BaseHTTPRequestHandler):
9191
...
9292
def do_GET(self):
9393
...
94-
url = AuthnRequest.create(**self.settings)
94+
url = AuthRequest.create(**self.settings)
9595
self.send_response(301)
9696
self.send_header("Location", url)
9797
self.end_headers()

example.py

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
log = logging.getLogger(__name__)
1717

18+
1819
class SampleAppHTTPRequestHandler(BaseHTTPRequestHandler):
1920
server_version = 'SampleAppHTTPRequestHandler/%s' % __version__
2021

@@ -57,7 +58,7 @@ def do_GET(self):
5758
self._bad_request()
5859
return
5960

60-
url = AuthnRequest.create(**self.settings)
61+
url = AuthRequest.create(**self.settings)
6162
self.send_response(301)
6263
self.send_header("Location", url)
6364
self.end_headers()
@@ -74,26 +75,27 @@ def do_POST(self):
7475
res = Response(
7576
query['SAMLResponse'].pop(),
7677
self.settings['idp_cert_fingerprint'],
77-
)
78+
)
7879
valid = res.is_valid()
7980
name_id = res.name_id
8081
if valid:
8182
msg = 'The identity of {name_id} has been verified'.format(
8283
name_id=name_id,
83-
)
84+
)
8485
self._serve_msg(200, msg)
8586
else:
8687
msg = '{name_id} is not authorized to use this resource'.format(
8788
name_id=name_id,
88-
)
89+
)
8990
self._serve_msg(401, msg)
9091

92+
9193
def main(config_file):
9294
logging.basicConfig(
9395
level=logging.INFO,
9496
format='%(asctime)s.%(msecs)03d example: %(levelname)s: %(message)s',
9597
datefmt='%Y-%m-%dT%H:%M:%S',
96-
)
98+
)
9799

98100
config = ConfigParser.RawConfigParser()
99101
config_path = os.path.expanduser(config_file)
@@ -109,27 +111,27 @@ def main(config_file):
109111
settings['assertion_consumer_service_url'] = config.get(
110112
'saml',
111113
'assertion_consumer_service_url'
112-
)
114+
)
113115
settings['issuer'] = config.get(
114116
'saml',
115117
'issuer'
116-
)
118+
)
117119
settings['name_identifier_format'] = config.get(
118120
'saml',
119121
'name_identifier_format'
120-
)
122+
)
121123
settings['idp_sso_target_url'] = config.get(
122124
'saml',
123125
'idp_sso_target_url'
124-
)
126+
)
125127
settings['idp_cert_file'] = config.get(
126128
'saml',
127129
'idp_cert_file'
128-
)
130+
)
129131
settings['idp_cert_fingerprint'] = config.get(
130132
'saml',
131133
'idp_cert_fingerprint'
132-
)
134+
)
133135

134136
cert_file = settings.pop('idp_cert_file', None)
135137

@@ -148,32 +150,32 @@ def main(config_file):
148150
httpd = HTTPServer(
149151
(host, port),
150152
SampleAppHTTPRequestHandler,
151-
)
153+
)
152154

153155
socket_name = httpd.socket.getsockname()
154156

155157
log.info(
156158
'Serving HTTP on {host} port {port} ...'.format(
157159
host=socket_name[0],
158160
port=socket_name[1],
159-
)
160161
)
162+
)
161163

162164
httpd.serve_forever()
163165

164166
if __name__ == '__main__':
165167
parser = optparse.OptionParser(
166168
usage='%prog [OPTS]',
167-
)
169+
)
168170
parser.add_option(
169171
'--config-file',
170172
metavar='PATH',
171173
help='The configuration file containing the app and SAML settings',
172-
)
174+
)
173175

174176
parser.set_defaults(
175177
config_file='example.cfg'
176-
)
178+
)
177179

178180
options, args = parser.parse_args()
179181
if args:

onelogin/saml/AuthRequest.py

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,29 @@
77
from lxml import etree
88
from lxml.builder import ElementMaker
99

10-
def create(
11-
_clock=None,
12-
_uuid=None,
13-
_zlib=None,
14-
_base64=None,
15-
_urllib=None,
16-
**kwargs
17-
):
18-
"""Create a URL string which can be used to redirect a samlp:AuthnRequest to the identity provider.
19-
Return a URL string containing the idp_sso_target_url and a deflated, base64-encoded, url-encoded (in that order) samlp:AuthnRequest XML element as the value of the SAMLRequest parameter.
10+
11+
def create(_clock=None, _uuid=None, _zlib=None, _base64=None,
12+
_urllib=None, **kwargs):
13+
"""Create a URL string which can be used to redirect a samlp:AuthnRequest
14+
to the identity provider. Return a URL string containing the
15+
idp_sso_target_url and a deflated, base64-encoded, url-encoded
16+
(in that order) samlp:AuthnRequest XML element as the value of the
17+
SAMLRequest parameter.
2018
2119
Keyword arguments:
22-
assertion_consumer_service_url -- The URL at which the SAML assertion should be received.
23-
issuer -- The name of your application. Some identity providers might need this to establish the identity of the service provider requesting the login.
24-
name_identifier_format -- The format of the username required by this application. If you need the email address, use "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress". See http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf section 8.3 for other options. Note that the identity provider might not support all options.
25-
idp_sso_target_url -- The URL to which the authentication request should be sent. This would be on the identity
20+
assertion_consumer_service_url -- The URL at which the SAML assertion
21+
should be received.
22+
issuer -- The name of your application. Some identity providers might need
23+
this to establish the identity of the service provider requesting
24+
the login.
25+
name_identifier_format -- The format of the username required by this
26+
application. If you need the email address, use
27+
"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress".
28+
See http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf
29+
section 8.3 for other options. Note that the
30+
identity provider might not support all options.
31+
idp_sso_target_url -- The URL to which the authentication request should be
32+
sent. This would be on the identity
2633
"""
2734
if _clock is None:
2835
_clock = datetime.utcnow
@@ -37,7 +44,7 @@ def create(
3744

3845
assertion_consumer_service_url = kwargs.pop(
3946
'assertion_consumer_service_url',
40-
)
47+
)
4148
issuer = kwargs.pop('issuer')
4249
name_identifier_format = kwargs.pop('name_identifier_format')
4350
idp_sso_target_url = kwargs.pop('idp_sso_target_url')
@@ -55,19 +62,19 @@ def create(
5562
samlp_maker = ElementMaker(
5663
namespace='urn:oasis:names:tc:SAML:2.0:protocol',
5764
nsmap=dict(samlp='urn:oasis:names:tc:SAML:2.0:protocol'),
58-
)
65+
)
5966
saml_maker = ElementMaker(
6067
namespace='urn:oasis:names:tc:SAML:2.0:assertion',
6168
nsmap=dict(saml='urn:oasis:names:tc:SAML:2.0:assertion'),
62-
)
69+
)
6370

6471
authn_request = samlp_maker.AuthnRequest(
6572
ProtocolBinding='urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
6673
Version='2.0',
6774
IssueInstant=now_iso,
6875
ID=unique_id,
6976
AssertionConsumerServiceURL=assertion_consumer_service_url,
70-
)
77+
)
7178

7279
saml_issuer = saml_maker.Issuer()
7380
saml_issuer.text = issuer
@@ -76,12 +83,12 @@ def create(
7683
name_id_policy = samlp_maker.NameIDPolicy(
7784
Format=name_identifier_format,
7885
AllowCreate='true',
79-
)
86+
)
8087
authn_request.append(name_id_policy)
8188

8289
request_authn_context = samlp_maker.RequestedAuthnContext(
8390
Comparison='exact',
84-
)
91+
)
8592
authn_request.append(request_authn_context)
8693

8794
authn_context_class_ref = saml_maker.AuthnContextClassRef()
@@ -96,9 +103,9 @@ def create(
96103
encoded_request = _base64.b64encode(deflated_request)
97104
urlencoded_request = _urllib.urlencode(
98105
[('SAMLRequest', encoded_request)],
99-
)
106+
)
100107

101108
return '{url}?{query}'.format(
102109
url=idp_sso_target_url,
103110
query=urlencoded_request,
104-
)
111+
)

onelogin/saml/Response.py

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55

66
from onelogin.saml import SignatureVerifier
77

8-
namespaces=dict(
8+
namespaces = dict(
99
samlp='urn:oasis:names:tc:SAML:2.0:protocol',
1010
saml='urn:oasis:names:tc:SAML:2.0:assertion',
11-
)
11+
)
12+
1213

1314
class ResponseValidationError(Exception):
1415
"""There was a problem validating the response"""
@@ -18,6 +19,7 @@ def __init__(self, msg):
1819
def __str__(self):
1920
return '%s: %s' % (self.__doc__, self._msg)
2021

22+
2123
class ResponseNameIDError(Exception):
2224
"""There was a problem getting the name ID"""
2325
def __init__(self, msg):
@@ -26,6 +28,7 @@ def __init__(self, msg):
2628
def __str__(self):
2729
return '%s: %s' % (self.__doc__, self._msg)
2830

31+
2932
class ResponseConditionError(Exception):
3033
"""There was a problem validating a condition"""
3134
def __init__(self, msg):
@@ -34,18 +37,13 @@ def __init__(self, msg):
3437
def __str__(self):
3538
return '%s: %s' % (self.__doc__, self._msg)
3639

40+
3741
class Response(object):
38-
def __init__(
39-
self,
40-
response,
41-
signature,
42-
_base64=None,
43-
_etree=None,
44-
):
42+
def __init__(self, response, signature, _base64=None, _etree=None):
4543
"""
4644
Extract information from an samlp:Response
4745
Arguments:
48-
response -- The base64 encoded, XML string containing the samlp:Response
46+
response -- The base64 encoded, XML string containing a samlp:Response
4947
signature -- The fingerprint to check the samlp:Response against
5048
"""
5149
if _base64 is None:
@@ -67,16 +65,16 @@ def _get_name_id(self):
6765
result = self._document.xpath(
6866
'/samlp:Response/saml:Assertion/saml:Subject/saml:NameID',
6967
namespaces=namespaces,
70-
)
68+
)
7169
length = len(result)
7270
if length > 1:
7371
raise ResponseNameIDError(
7472
'Found more than one name ID'
75-
)
73+
)
7674
if length == 0:
7775
raise ResponseNameIDError(
7876
'Did not find a name ID'
79-
)
77+
)
8078

8179
node = result.pop()
8280

@@ -85,20 +83,16 @@ def _get_name_id(self):
8583
name_id = property(
8684
fget=_get_name_id,
8785
doc="The value requested in the name_identifier_format, e.g., the user's email address",
88-
)
86+
)
8987

90-
def get_assertion_attribute_value(self,attribute_name):
88+
def get_assertion_attribute_value(self, attribute_name):
9189
"""
9290
Get the value of an AssertionAttribute, located in an Assertion/AttributeStatement/Attribute[@Name=attribute_name/AttributeValue tag
9391
"""
94-
result = self._document.xpath('/samlp:Response/saml:Assertion/saml:AttributeStatement/saml:Attribute[@Name="%s"]/saml:AttributeValue'%attribute_name,namespaces=namespaces)
92+
result = self._document.xpath('/samlp:Response/saml:Assertion/saml:AttributeStatement/saml:Attribute[@Name="%s"]/saml:AttributeValue' % attribute_name, namespaces=namespaces)
9593
return [n.text.strip() for n in result]
9694

97-
def is_valid(
98-
self,
99-
_clock=None,
100-
_verifier=None,
101-
):
95+
def is_valid(self, _clock=None, _verifier=None):
10296
"""
10397
Verify that the samlp:Response is valid.
10498
Return True if valid, otherwise False.
@@ -111,7 +105,7 @@ def is_valid(
111105
conditions = self._document.xpath(
112106
'/samlp:Response/saml:Assertion/saml:Conditions',
113107
namespaces=namespaces,
114-
)
108+
)
115109

116110
now = _clock()
117111

@@ -123,7 +117,7 @@ def is_valid(
123117

124118
if not_before is None:
125119
#notbefore condition is not mandatory. If it is not specified, use yesterday as not_before condition
126-
not_before = (now-timedelta(1,0,0)).strftime('%Y-%m-%dT%H:%M:%SZ')
120+
not_before = (now - timedelta(1, 0, 0)).strftime('%Y-%m-%dT%H:%M:%SZ')
127121
if not_on_or_after is None:
128122
raise ResponseConditionError('Did not find NotOnOrAfter condition')
129123

@@ -133,13 +127,13 @@ def is_valid(
133127
if now < not_before:
134128
raise ResponseValidationError(
135129
'Current time is earlier than NotBefore condition'
136-
)
130+
)
137131
if now >= not_on_or_after:
138132
raise ResponseValidationError(
139133
'Current time is on or after NotOnOrAfter condition'
140-
)
134+
)
141135

142136
return _verifier(
143137
self._document,
144138
self._signature,
145-
)
139+
)

0 commit comments

Comments
 (0)