OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 (function() { |
| 6 |
| 7 'use strict'; |
| 8 |
| 9 var testUsername = 'testUsername@gmail.com'; |
| 10 var testToken = 'testToken'; |
| 11 |
| 12 var sendMessage = null; |
| 13 var startTls = null; |
| 14 var onHandshakeDone = null; |
| 15 var onStanzaStr = null; |
| 16 var onError = null; |
| 17 var loginHandler = null; |
| 18 |
| 19 module('XmppLoginHandler', { |
| 20 setup: function() { |
| 21 sendMessage = sinon.spy(); |
| 22 startTls = sinon.spy(); |
| 23 onHandshakeDone = sinon.spy(); |
| 24 onStanzaStr = sinon.spy(); |
| 25 onError = sinon.spy(); |
| 26 function onStanza(stanza) { |
| 27 onStanzaStr(new XMLSerializer().serializeToString(stanza)); |
| 28 } |
| 29 loginHandler = new remoting.XmppLoginHandler( |
| 30 'google.com', testUsername, testToken, sendMessage, startTls, |
| 31 onHandshakeDone, onError); |
| 32 } |
| 33 }); |
| 34 |
| 35 // Executes handshake base. |
| 36 function handshakeBase() { |
| 37 loginHandler.start(); |
| 38 sinon.assert.calledWith( |
| 39 sendMessage, |
| 40 '<stream:stream to="google.com" version="1.0" xmlns="jabber:client" ' + |
| 41 'xmlns:stream="http://etherx.jabber.org/streams">'); |
| 42 sendMessage.reset(); |
| 43 |
| 44 loginHandler.onDataReceived(base.encodeUtf8( |
| 45 '<stream:stream from="google.com" id="78A87C70559EF28A" version="1.0" ' + |
| 46 'xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">' + |
| 47 '<stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls">' + |
| 48 '<required/></starttls><mechanisms ' + |
| 49 'xmlns="urn:ietf:params:xml:ns:xmpp-sasl">' + |
| 50 '<mechanism>X-OAUTH2</mechanism><mechanism>X-GOOGLE-TOKEN</mechanism>' + |
| 51 '</mechanisms></stream:features>')); |
| 52 sinon.assert.calledWith( |
| 53 sendMessage, '<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>'); |
| 54 sendMessage.reset(); |
| 55 |
| 56 loginHandler.onDataReceived( |
| 57 base.encodeUtf8('<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>')); |
| 58 sinon.assert.calledWith(startTls); |
| 59 startTls.reset(); |
| 60 |
| 61 loginHandler.onTlsStarted(); |
| 62 sinon.assert.calledWith( |
| 63 sendMessage, |
| 64 '<stream:stream to="google.com" version="1.0" xmlns="jabber:client" ' + |
| 65 'xmlns:stream="http://etherx.jabber.org/streams">'); |
| 66 sendMessage.reset(); |
| 67 |
| 68 loginHandler.onDataReceived(base.encodeUtf8( |
| 69 '<stream:stream from="google.com" id="DCDDE5171CB2154A" version="1.0" ' + |
| 70 'xmlns:stream="http://etherx.jabber.org/streams" ' + |
| 71 'xmlns="jabber:client"><stream:features>' + |
| 72 '<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">' + |
| 73 '<mechanism>X-OAUTH2</mechanism><mechanism>X-GOOGLE-TOKEN</mechanism>' + |
| 74 '<mechanism>PLAIN</mechanism></mechanisms></stream:features>')); |
| 75 var cookie = window.btoa("\0" + testUsername + "\0" + testToken); |
| 76 sinon.assert.calledWith( |
| 77 sendMessage, |
| 78 '<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="X-OAUTH2" ' + |
| 79 'auth:service="oauth2" auth:allow-generated-jid="true" ' + |
| 80 'auth:client-uses-full-bind-result="true" ' + |
| 81 'auth:allow-non-google-login="true" ' + |
| 82 'xmlns:auth="http://www.google.com/talk/protocol/auth">' + cookie + |
| 83 '</auth>'); |
| 84 sendMessage.reset(); |
| 85 } |
| 86 |
| 87 test('should authenticate', function() { |
| 88 handshakeBase(); |
| 89 |
| 90 loginHandler.onDataReceived( |
| 91 base.encodeUtf8('<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>')); |
| 92 sinon.assert.calledWith( |
| 93 sendMessage, |
| 94 '<stream:stream to="google.com" version="1.0" xmlns="jabber:client" ' + |
| 95 'xmlns:stream="http://etherx.jabber.org/streams">'); |
| 96 sendMessage.reset(); |
| 97 |
| 98 loginHandler.onDataReceived(base.encodeUtf8( |
| 99 '<stream:stream from="google.com" id="104FA10576E2AA80" version="1.0" ' + |
| 100 'xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">' + |
| 101 '<stream:features><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>' + |
| 102 '<session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>' + |
| 103 '</stream:features>')); |
| 104 sinon.assert.calledWith( |
| 105 sendMessage, |
| 106 '<iq type="set" id="0"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">' + |
| 107 '<resource>chromoting</resource></bind></iq>'); |
| 108 sendMessage.reset(); |
| 109 |
| 110 loginHandler.onDataReceived( |
| 111 base.encodeUtf8('<iq id="0" type="result">' + |
| 112 '<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>' + |
| 113 testUsername + '/chromoting52B4920E</jid></bind></iq>')); |
| 114 sinon.assert.calledWith( |
| 115 sendMessage, |
| 116 '<iq type="set" id="1"><session ' + |
| 117 'xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>'); |
| 118 sendMessage.reset(); |
| 119 |
| 120 loginHandler.onDataReceived(base.encodeUtf8('<iq type="result" id="1"/>')); |
| 121 sinon.assert.calledWith(onHandshakeDone); |
| 122 }); |
| 123 |
| 124 test('should return AUTHENTICATION_FAILED error when failed to authenticate', |
| 125 function() { |
| 126 handshakeBase(); |
| 127 |
| 128 loginHandler.onDataReceived( |
| 129 base.encodeUtf8('<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl">' + |
| 130 '<not-authorized/></failure>')); |
| 131 sinon.assert.calledWith(onError, remoting.Error.AUTHENTICATION_FAILED); |
| 132 }); |
| 133 |
| 134 test('should return UNEXPECTED error when failed to parse stream', |
| 135 function() { |
| 136 loginHandler.start(); |
| 137 loginHandler.onDataReceived( |
| 138 base.encodeUtf8('BAD DATA')); |
| 139 sinon.assert.calledWith(onError, remoting.Error.UNEXPECTED); |
| 140 }); |
| 141 |
| 142 })(); |
OLD | NEW |