Ticket #232: THE.diff

File THE.diff, 17.3 kB (added by http://keturn.myopenid.com/, 6 months ago)

A diff for this change that will also fix several other tickets

  • old-openid/openid/consumer/consumer.py

    old new  
    14711461        self.assoc = assoc 
    14721462        self.endpoint = endpoint 
    14731463        self.return_to_args = {} 
    1474         self.message = Message() 
    1475         self.message.setOpenIDNamespace(endpoint.preferredNamespace()) 
     1464        self.message = Message(endpoint.preferredNamespace()) 
    14761465        self._anonymous = False 
    14771466 
    14781467    def setAnonymous(self, is_anonymous): 
  • old-openid/openid/message.py

    old new  
    2626 
    2727# The OpenID 1.X namespace URI 
    2828OPENID1_NS = 'http://openid.net/signon/1.0' 
     29THE_OTHER_OPENID1_NS = 'http://openid.net/signon/1.1' 
     30 
     31OPENID1_NAMESPACES = OPENID1_NS, THE_OTHER_OPENID1_NS 
    2932 
    3033# The OpenID 2.0 namespace URI 
    3134OPENID2_NS = 'http://specs.openid.net/auth/2.0' 
     
    109124        URI. 
    110125    """ 
    111126 
    112     allowed_openid_namespaces = [OPENID1_NS, OPENID2_NS] 
     127    allowed_openid_namespaces = [OPENID1_NS, THE_OTHER_OPENID1_NS, OPENID2_NS] 
    113128 
    114129    def __init__(self, openid_namespace=None): 
    115130        """Create an empty Message. 
    116131 
    117132 
    118133        @raises InvalidOpenIDNamespace: if openid_namespace is not in 
    119134            L{Message.allowed_openid_namespaces} 
    120135        """ 
    121136        self.args = {} 
    122137        self.namespaces = NamespaceMap() 
    123138        if openid_namespace is None: 
    124139            self._openid_ns_uri = None 
    125140        else: 
    126             self.setOpenIDNamespace(openid_namespace) 
     141            implicit = openid_namespace in OPENID1_NAMESPACES 
     142            self.setOpenIDNamespace(openid_namespace, implicit) 
    127143 
    128144    def fromPostArgs(cls, args): 
    129145        """Construct a Message containing a set of POST arguments. """ 
    130146        self = cls() 
    131147 
    132148        # Partition into "openid." args and bare args 
     
    157184    fromOpenIDArgs = classmethod(fromOpenIDArgs) 
    158185 
    159186    def _fromOpenIDArgs(self, openid_args): 
    160         global registered_aliases 
    161  
    162187        ns_args = [] 
    163188 
    164189        # Resolve namespaces 
     
    173198                self.namespaces.addAlias(value, ns_key) 
    174199            elif ns_alias == NULL_NAMESPACE and ns_key == 'ns': 
    175200                # null namespace 
    176                 self.namespaces.addAlias(value, NULL_NAMESPACE
     201                self.setOpenIDNamespace(value, False
    177202            else: 
    178203                ns_args.append((ns_alias, ns_key, value)) 
    179204 
    180         # Ensure that there is an OpenID namespace definition 
    181         openid_ns_uri = self.namespaces.getNamespaceURI(NULL_NAMESPACE) 
    182         if openid_ns_uri is None: 
    183             openid_ns_uri = OPENID1_NS 
    184  
    185         self.setOpenIDNamespace(openid_ns_uri) 
     205        # Implicitly set an OpenID namespace definition (OpenID 1) 
     206        if not self.getOpenIDNamespace(): 
     207            self.setOpenIDNamespace(OPENID1_NS, True) 
    186208 
    187209        # Actually put the pairs into the appropriate namespaces 
    188210        for (ns_alias, ns_key, value) in ns_args: 
    189211            ns_uri = self.namespaces.getNamespaceURI(ns_alias) 
    190212            if ns_uri is None: 
    191213                # we found a namespaced arg without a namespace URI defined 
    192214                ns_uri = self._getDefaultNamespace(ns_alias) 
    193215                if ns_uri is None: 
    194216                    ns_uri = self.getOpenIDNamespace() 
    195217                    ns_key = '%s.%s' % (ns_alias, ns_key) 
    196218                else: 
    197219                    self.namespaces.addAlias(ns_uri, ns_alias, implicit=True) 
    198220 
    199221            self.setArg(ns_uri, ns_key, value) 
    200222 
    201     def setOpenIDNamespace(self, openid_ns_uri): 
     223    def setOpenIDNamespace(self, openid_ns_uri, implicit): 
     224        """Set the OpenID namespace URI used in this message. 
     225 
     226        @raises InvalidOpenIDNamespace: if the namespace is not in 
     227            L{Message.allowed_openid_namespaces} 
     228        """ 
    202229        if openid_ns_uri not in self.allowed_openid_namespaces: 
    203             raise ValueError('Invalid null namespace: %r' % (openid_ns_uri,)
     230            raise InvalidOpenIDNamespace(openid_ns_uri
    204231 
    205         self.namespaces.addAlias(openid_ns_uri, NULL_NAMESPACE
     232        self.namespaces.addAlias(openid_ns_uri, NULL_NAMESPACE, implicit
    206233        self._openid_ns_uri = openid_ns_uri 
    207234 
    208235    def getOpenIDNamespace(self): 
    209236        return self._openid_ns_uri 
    210237 
    211238    def isOpenID1(self): 
    212         return self.getOpenIDNamespace() == OPENID1_N
     239        return self.getOpenIDNamespace() in OPENID1_NAMESPACE
    213240 
    214241    def isOpenID2(self): 
    215242        return self.getOpenIDNamespace() == OPENID2_NS 
  • old-openid/openid/test/test_consumer.py

    old new  
    11761176        assert args == { 
    11771177            'openid.mode':'check_authentication', 
    11781178            'openid.signed':'foo', 
     1179            'openid.ns':OPENID1_NS 
    11791180            }, args 
    11801181        return None 
    11811182 
     
    12181219    def test_signedList(self): 
    12191220        query = Message.fromOpenIDArgs({ 
    12201221            'mode': 'id_res', 
    1221             'ns': OPENID2_NS, 
    12221222            'sig': 'rabbits', 
    12231223            'identity': '=example', 
    12241224            'assoc_handle': 'munchkins', 
     
    12271227            'signed': 'identity,mode,ns.sreg,sreg.email', 
    12281228            'foo': 'bar', 
    12291229            }) 
    1230         expected = Message.fromOpenIDArgs({ 
    1231             'mode': 'check_authentication', 
    1232             'sig': 'rabbits', 
    1233             'assoc_handle': 'munchkins', 
    1234             'identity': '=example', 
    1235             'signed': 'identity,mode,ns.sreg,sreg.email', 
    1236             'ns.sreg': 'urn:sreg', 
    1237             'sreg.email': 'bogus@example.com', 
    1238             }) 
    12391230        args = self.consumer._createCheckAuthRequest(query) 
    1240         self.failUnlessEqual(args.toPostArgs(), expected.toPostArgs()) 
     1231        self.failUnless(args.isOpenID1()) 
     1232        for signed_arg in query.getArg(OPENID_NS, 'signed').split(','): 
     1233           self.failUnless(args.getAliasedArg(signed_arg), signed_arg) 
     1234 
     1235    def test_112(self): 
     1236        args = {'openid.assoc_handle': 'fa1f5ff0-cde4-11dc-a183-3714bfd55ca8', 
     1237                'openid.claimed_id': 'http://binkley.lan/user/test01', 
     1238                'openid.identity': 'http://test01.binkley.lan/', 
     1239                'openid.mode': 'id_res', 
     1240                'openid.ns': 'http://specs.openid.net/auth/2.0', 
     1241                'openid.ns.pape': 'http://specs.openid.net/extensions/pape/1.0', 
     1242                'openid.op_endpoint': 'http://binkley.lan/server', 
     1243                'openid.pape.auth_policies': 'none', 
     1244                'openid.pape.auth_time': '2008-01-28T20:42:36Z', 
     1245                'openid.pape.nist_auth_level': '0', 
     1246                'openid.response_nonce': '2008-01-28T21:07:04Z99Q=', 
     1247                'openid.return_to': 'http://binkley.lan:8001/process?janrain_nonce=2008-01-28T21%3A07%3A02Z0tMIKx', 
     1248                'openid.sig': 'YJlWH4U6SroB1HoPkmEKx9AyGGg=', 
     1249                'openid.signed': 'assoc_handle,identity,response_nonce,return_to,claimed_id,op_endpoint,pape.auth_time,ns.pape,pape.nist_auth_level,pape.auth_policies' 
     1250                } 
     1251        self.failUnlessEqual(OPENID2_NS, args['openid.ns']) 
     1252        incoming = Message.fromPostArgs(args) 
     1253        self.failUnless(incoming.isOpenID2()) 
     1254        car = self.consumer._createCheckAuthRequest(incoming) 
     1255        expected_args = args.copy() 
     1256        expected_args['openid.mode'] = 'check_authentication' 
     1257        expected =Message.fromPostArgs(expected_args) 
     1258        self.failUnless(expected.isOpenID2()) 
     1259        self.failUnlessEqual(expected, car) 
     1260        self.failUnlessEqual(expected_args, car.toPostArgs()) 
    12411261 
    12421262 
    12431263 
  • old-openid/openid/test/test_message.py

    old new  
    11from openid import message 
    22from openid import oidutil 
     3from openid.extensions import sreg 
    34 
    45import urllib 
    56import cgi 
     
    400401    def test_isOpenID2(self): 
    401402        self.failIf(self.msg.isOpenID2()) 
    402403 
    403 class OpenID1ExplicitMessageTest(OpenID1MessageTest): 
     404class OpenID1ExplicitMessageTest(unittest.TestCase): 
    404405    def setUp(self): 
    405406        self.msg = message.Message.fromPostArgs({'openid.mode':'error', 
    406407                                                 'openid.error':'unit test', 
    407408                                                 'openid.ns':message.OPENID1_NS 
    408409                                                 }) 
    409410 
     411    def test_toPostArgs(self): 
     412        self.failUnlessEqual(self.msg.toPostArgs(), 
     413                             {'openid.mode':'error', 
     414                              'openid.error':'unit test', 
     415                              'openid.ns':message.OPENID1_NS 
     416                              }) 
     417 
     418    def test_toArgs(self): 
     419        self.failUnlessEqual(self.msg.toArgs(), {'mode':'error', 
     420                                                 'error':'unit test', 
     421                                                 'ns':message.OPENID1_NS}) 
     422 
     423    def test_toKVForm(self): 
     424        self.failUnlessEqual(self.msg.toKVForm(), 
     425                             'error:unit test\nmode:error\nns:%s\n' 
     426                              %message.OPENID1_NS) 
     427 
     428    def test_toURLEncoded(self): 
     429        self.failUnlessEqual(self.msg.toURLEncoded(), 
     430                             'openid.error=unit+test&openid.mode=error&openid.ns=http%3A%2F%2Fopenid.net%2Fsignon%2F1.0') 
     431 
     432    def test_toURL(self): 
     433        base_url = 'http://base.url/' 
     434        actual = self.msg.toURL(base_url) 
     435        actual_base = actual[:len(base_url)] 
     436        self.failUnlessEqual(actual_base, base_url) 
     437        self.failUnlessEqual(actual[len(base_url)], '?') 
     438        query = actual[len(base_url) + 1:] 
     439        parsed = cgi.parse_qs(query) 
     440        self.failUnlessEqual(parsed, {'openid.mode':['error'], 
     441                                      'openid.error':['unit test'], 
     442                                      'openid.ns':[message.OPENID1_NS] 
     443                                      }) 
     444 
     445    def test_isOpenID1(self): 
     446        self.failUnless(self.msg.isOpenID1()) 
     447 
    410448 
    411449class OpenID2MessageTest(unittest.TestCase): 
    412450    def setUp(self): 
     
    769769        self._checkForm(html, m, self.action_url, 
    770770                        tag_attrs, self.submit_text) 
    771771 
     772 
     773    def test_setOpenIDNamespace_invalid(self): 
     774        m = message.Message() 
     775        invalid_things = [ 
     776            # Empty string is not okay here. 
     777            '', 
     778            # Good guess!  But wrong. 
     779            'http://openid.net/signon/2.0', 
     780            # What? 
     781            u'http://specs%\\\r2Eopenid.net/auth/2.0', 
     782            # Too much escapings! 
     783            'http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0', 
     784            # This is a Type URI, not a openid.ns value. 
     785            'http://specs.openid.net/auth/2.0/signon', 
     786            ] 
     787 
     788        for x in invalid_things: 
     789            self.failUnlessRaises(message.InvalidOpenIDNamespace, 
     790                                  m.setOpenIDNamespace, x, False) 
     791 
     792 
     793    def test_isOpenID1(self): 
     794        v1_namespaces = [ 
     795            # Yes, there are two of them. 
     796            'http://openid.net/signon/1.1', 
     797            'http://openid.net/signon/1.0', 
     798            ] 
     799 
     800        for ns in v1_namespaces: 
     801            m = message.Message(ns) 
     802            self.failUnless(m.isOpenID1(), "%r not recognized as OpenID 1" % 
     803                            (ns,)) 
     804            self.failUnlessEqual(ns, m.getOpenIDNamespace()) 
     805            self.failUnless(m.namespaces.isImplicit(ns), 
     806                            m.namespaces.getNamespaceURI(message.NULL_NAMESPACE)) 
     807 
     808    def test_isOpenID2(self): 
     809        ns = 'http://specs.openid.net/auth/2.0' 
     810        m = message.Message(ns) 
     811        self.failUnless(m.isOpenID2()) 
     812        self.failIf(m.namespaces.isImplicit(message.NULL_NAMESPACE)) 
     813        self.failUnlessEqual(ns, m.getOpenIDNamespace()) 
     814 
     815    def test_setOpenIDNamespace_explicit(self): 
     816        m = message.Message() 
     817        m.setOpenIDNamespace(message.THE_OTHER_OPENID1_NS, False) 
     818        self.failIf(m.namespaces.isImplicit(message.THE_OTHER_OPENID1_NS)) 
     819 
     820    def test_setOpenIDNamespace_implicit(self): 
     821        m = message.Message() 
     822        m.setOpenIDNamespace(message.THE_OTHER_OPENID1_NS, True) 
     823        self.failUnless(m.namespaces.isImplicit(message.THE_OTHER_OPENID1_NS)) 
     824 
     825 
     826    def test_explicitOpenID11NSSerialzation(self): 
     827        m = message.Message() 
     828        m.setOpenIDNamespace(message.THE_OTHER_OPENID1_NS, implicit=False) 
     829 
     830        post_args = m.toPostArgs() 
     831        self.failUnlessEqual(post_args, 
     832                             {'openid.ns':message.THE_OTHER_OPENID1_NS}) 
     833 
     834    def test_fromPostArgs_ns11(self): 
     835        # An example of the stuff that some Drupal installations send us, 
     836        # which includes openid.ns but is 1.1. 
     837        query = { 
     838            u'openid.assoc_handle': u'', 
     839            u'openid.claimed_id': u'http://foobar.invalid/', 
     840            u'openid.identity': u'http://foobar.myopenid.com', 
     841            u'openid.mode': u'checkid_setup', 
     842            u'openid.ns': u'http://openid.net/signon/1.1', 
     843            u'openid.ns.sreg': u'http://openid.net/extensions/sreg/1.1', 
     844            u'openid.return_to': u'http://drupal.invalid/return_to', 
     845            u'openid.sreg.required': u'nickname,email', 
     846            u'openid.trust_root': u'http://drupal.invalid', 
     847            } 
     848        m = message.Message.fromPostArgs(query) 
     849        self.failUnless(m.isOpenID1()) 
     850 
     851 
     852 
    772853class NamespaceMapTest(unittest.TestCase): 
    773854    def test_onealias(self): 
    774855        nsm = message.NamespaceMap() 
  • old-openid/openid/test/test_server.py

    old new  
    945970                             len(expected_list) + 2, 
    946971                             answer.fields.toPostArgs()) 
    947972 
    948     def _expectAnswerv1(self, answer, identity=None): 
    949         expected_list = [ 
    950             ('mode', 'id_res'), 
    951             ('return_to', self.request.return_to), 
    952             ('identity', identity), 
    953             ] 
    954  
    955         for k, expected in expected_list: 
    956             actual = answer.fields.getArg(OPENID_NS, k) 
    957             self.failUnlessEqual(actual, expected, "%s: expected %s, got %s" % (k, expected, actual)) 
    958  
    959         self.failUnless(answer.fields.hasKey(OPENID_NS, 'response_nonce')) 
    960         self.failUnlessEqual(answer.fields.getOpenIDNamespace(), OPENID1_NS) 
    961  
    962         # One for nonce 
    963         self.failUnlessEqual(len(answer.fields.toPostArgs()), 
    964                              len(expected_list) + 1, 
    965                              answer.fields.toPostArgs()) 
    966  
    967  
    968973    def test_answerAllow(self): 
    969974        """Check the fields specified by "Positive Assertions" 
    970975 
     
    11101154        """Test .allow() with an OpenID 1.x Message on a CheckIDRequest 
    11111155        built without an op_endpoint parameter. 
    11121156        """ 
     1157        identity = 'http://bambam.unittest/' 
    11131158        reqmessage = Message.fromOpenIDArgs({ 
    1114             'identity': 'http://bambam.unittest/'
     1159            'identity': identity
    11151160            'trust_root': 'http://bar.unittest/', 
    11161161            'return_to': 'http://bar.unittest/999', 
    11171162            }) 
    11181163        self.request = server.CheckIDRequest.fromMessage(reqmessage, None) 
    11191164        answer = self.request.answer(True) 
    1120         self._expectAnswerv1(answer, 'http://bambam.unittest/') 
     1165 
     1166        expected_list = [ 
     1167            ('mode', 'id_res'), 
     1168            ('return_to', self.request.return_to), 
     1169            ('identity', identity), 
     1170            ] 
     1171 
     1172        for k, expected in expected_list: 
     1173            actual = answer.fields.getArg(OPENID_NS, k) 
     1174            self.failUnlessEqual( 
     1175                expected, actual, 
     1176                "%s: expected %s, got %s" % (k, expected, actual)) 
     1177 
     1178        self.failUnless(answer.fields.hasKey(OPENID_NS, 'response_nonce')) 
     1179        self.failUnlessEqual(answer.fields.getOpenIDNamespace(), OPENID1_NS) 
     1180        self.failUnless(answer.fields.namespaces.isImplicit(OPENID1_NS)) 
     1181 
     1182        # One for nonce (OpenID v1 namespace is implicit) 
     1183        self.failUnlessEqual(len(answer.fields.toPostArgs()), 
     1184                             len(expected_list) + 1, 
     1185                             answer.fields.toPostArgs()) 
    11211186 
    11221187    def test_answerImmediateDenyOpenID2(self): 
    11231188        """Look for mode=setup_needed in checkid_immediate negative 
     
    11501215        self.failUnlessEqual(answer.request, self.request) 
    11511216        self.failUnlessEqual(len(answer.fields.toPostArgs()), 2, answer.fields) 
    11521217        self.failUnlessEqual(answer.fields.getOpenIDNamespace(), OPENID1_NS) 
     1218        self.failUnless(answer.fields.namespaces.isImplicit(OPENID1_NS)) 
    11531219        self.failUnlessEqual(answer.fields.getArg(OPENID_NS, 'mode'), 'id_res') 
    11541220        self.failUnless(answer.fields.getArg( 
    11551221            OPENID_NS, 'user_setup_url', '').startswith(server_url)) 
     
    12021268            immediate = False, 
    12031269            op_endpoint = self.server.op_endpoint, 
    12041270            ) 
     1271        self.request.message = Message(OPENID2_NS) 
    12051272        self.response = server.OpenIDResponse(self.request) 
    12061273        self.response.fields.setArg(OPENID_NS, 'mode', 'id_res') 
    12071274        self.response.fields.setArg(OPENID_NS, 'blue', 'star')