Skip to content

Commit 008e8f7

Browse files
author
tailor
committed
[project @ pape5: support special "none" policy URI]
1 parent 332dc16 commit 008e8f7

File tree

2 files changed

+80
-5
lines changed

2 files changed

+80
-5
lines changed

openid/extensions/draft/pape5.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
'AUTH_PHISHING_RESISTANT',
1414
'AUTH_MULTI_FACTOR',
1515
'AUTH_MULTI_FACTOR_PHYSICAL',
16-
'AUTH_NONE',
1716
'LEVELS_NIST',
1817
'LEVELS_JISA',
1918
]
2019

2120
from openid.extension import Extension
21+
import warnings
2222
import re
2323

2424
ns_uri = "http://specs.openid.net/extensions/pape/1.0"
@@ -271,6 +271,9 @@ def preferredTypes(self, supported_types):
271271
class Response(PAPEExtension):
272272
"""A Provider Authentication Policy response, sent from a provider
273273
to a relying party
274+
275+
@ivar auth_policies: List of authentication policies conformed to
276+
by this OpenID assertion, represented as policy URIs
274277
"""
275278

276279
ns_alias = 'pape'
@@ -338,6 +341,10 @@ def addPolicyURI(self, policy_uri):
338341
authentication.
339342
@see: http://openid.net/specs/openid-provider-authentication-policy-extension-1_0-01.html#auth_policies
340343
"""
344+
if policy_uri == AUTH_NONE:
345+
raise RuntimeError(
346+
'To send no policies, do not set any on the response.')
347+
341348
if policy_uri not in self.auth_policies:
342349
self.auth_policies.append(policy_uri)
343350

@@ -382,8 +389,28 @@ def parseExtensionArgs(self, args, strict=False):
382389
this object.
383390
"""
384391
policies_str = args.get('auth_policies')
385-
if policies_str and policies_str != 'none':
386-
self.auth_policies = policies_str.split(' ')
392+
if policies_str:
393+
auth_policies = policies_str.split(' ')
394+
elif strict:
395+
raise ValueError('Missing auth_policies')
396+
else:
397+
auth_policies = []
398+
399+
if (len(auth_policies) > 1 and strict and AUTH_NONE in auth_policies):
400+
raise ValueError('Got some auth policies, as well as the special '
401+
'"none" URI: %r' % (auth_policies,))
402+
403+
if 'none' in auth_policies:
404+
msg = '"none" used as a policy URI (see PAPE draft < 5)'
405+
if strict:
406+
raise ValueError(msg)
407+
else:
408+
warnings.warn(msg, stacklevel=2)
409+
410+
auth_policies = [u for u in auth_policies
411+
if u not in ['none', AUTH_NONE]]
412+
413+
self.auth_policies = auth_policies
387414

388415
for (key, val) in args.iteritems():
389416
if key.startswith('auth_level.'):
@@ -418,7 +445,7 @@ def getExtensionArgs(self):
418445
"""
419446
if len(self.auth_policies) == 0:
420447
ns_args = {
421-
'auth_policies':'none',
448+
'auth_policies': AUTH_NONE,
422449
}
423450
else:
424451
ns_args = {

openid/test/test_pape_draft5.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
from openid.message import *
44
from openid.server import server
55

6+
import warnings
7+
warnings.filterwarnings('ignore', module=__name__,
8+
message='"none" used as a policy URI')
9+
610
import unittest
711

812
class PapeRequestTestCase(unittest.TestCase):
@@ -246,8 +250,11 @@ def test_add_policy_uri(self):
246250
pape.AUTH_PHISHING_RESISTANT],
247251
self.resp.auth_policies)
248252

253+
self.failUnlessRaises(RuntimeError, self.resp.addPolicyURI,
254+
pape.AUTH_NONE)
255+
249256
def test_getExtensionArgs(self):
250-
self.failUnlessEqual({'auth_policies': 'none'},
257+
self.failUnlessEqual({'auth_policies': pape.AUTH_NONE},
251258
self.resp.getExtensionArgs())
252259
self.resp.addPolicyURI('http://uri')
253260
self.failUnlessEqual({'auth_policies': 'http://uri'},
@@ -280,11 +287,52 @@ def test_parseExtensionArgs(self):
280287
self.failUnlessEqual(['http://foo','http://bar'],
281288
self.resp.auth_policies)
282289

290+
def test_parseExtensionArgs_valid_none(self):
291+
args = {'auth_policies': pape.AUTH_NONE}
292+
self.resp.parseExtensionArgs(args)
293+
self.failUnlessEqual([], self.resp.auth_policies)
294+
295+
def test_parseExtensionArgs_old_none(self):
296+
args = {'auth_policies': 'none'}
297+
self.resp.parseExtensionArgs(args)
298+
self.failUnlessEqual([], self.resp.auth_policies)
299+
300+
def test_parseExtensionArgs_old_none_strict(self):
301+
args = {'auth_policies': 'none'}
302+
self.failUnlessRaises(ValueError,
303+
self.resp.parseExtensionArgs, args, strict=True)
304+
283305
def test_parseExtensionArgs_empty(self):
284306
self.resp.parseExtensionArgs({})
285307
self.failUnlessEqual(None, self.resp.auth_time)
286308
self.failUnlessEqual([], self.resp.auth_policies)
287309

310+
def test_parseExtensionArgs_empty_strict(self):
311+
self.failUnlessRaises(ValueError,
312+
self.resp.parseExtensionArgs, {}, strict=True)
313+
314+
def test_parseExtensionArgs_ignore_superfluous_none(self):
315+
policies = [pape.AUTH_NONE, pape.AUTH_MULTI_FACTOR_PHYSICAL]
316+
317+
args = {
318+
'auth_policies': ' '.join(policies),
319+
}
320+
321+
self.resp.parseExtensionArgs(args, strict=False)
322+
323+
self.assertEqual([pape.AUTH_MULTI_FACTOR_PHYSICAL],
324+
self.resp.auth_policies)
325+
326+
def test_parseExtensionArgs_none_strict(self):
327+
policies = [pape.AUTH_NONE, pape.AUTH_MULTI_FACTOR_PHYSICAL]
328+
329+
args = {
330+
'auth_policies': ' '.join(policies),
331+
}
332+
333+
self.failUnlessRaises(ValueError, self.resp.parseExtensionArgs,
334+
args, strict=True)
335+
288336
def test_parseExtensionArgs_strict_bogus1(self):
289337
args = {'auth_policies': 'http://foo http://bar',
290338
'auth_time': 'yesterday'}

0 commit comments

Comments
 (0)