summaryrefslogtreecommitdiff
path: root/toolkit/identity/tests/unit/test_authentication.js
blob: 3f24e2e37d1755588a222f9b1252e25bb70d9855 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

XPCOMUtils.defineLazyModuleGetter(this, "IDService",
                                  "resource://gre/modules/identity/Identity.jsm",
                                  "IdentityService");

XPCOMUtils.defineLazyModuleGetter(this, "jwcrypto",
                                  "resource://gre/modules/identity/jwcrypto.jsm");

function test_begin_authentication_flow() {
  do_test_pending();
  let _provId = null;

  // set up a watch, to be consistent
  let mockedDoc = mock_doc(null, TEST_URL, function(action, params) {});
  IDService.RP.watch(mockedDoc);

  // The identity-auth notification is sent up to the UX from the
  // _doAuthentication function.  Be ready to receive it and call
  // beginAuthentication
  makeObserver("identity-auth", function (aSubject, aTopic, aData) {
    do_check_neq(aSubject, null);

    do_check_eq(aSubject.wrappedJSObject.provId, _provId);

    do_test_finished();
    run_next_test();
  });

  setup_provisioning(
    TEST_USER,
    function(caller) {
      _provId = caller.id;
      IDService.IDP.beginProvisioning(caller);
    }, function() {},
    {
      beginProvisioningCallback: function(email, duration_s) {

        // let's say this user needs to authenticate
        IDService.IDP._doAuthentication(_provId, {idpParams:TEST_IDPPARAMS});
      }
    }
  );
}

function test_complete_authentication_flow() {
  do_test_pending();
  let _provId = null;
  let _authId = null;
  let id = TEST_USER;

  let callbacksFired = false;
  let loginStateChanged = false;
  let identityAuthComplete = false;

  // The result of authentication should be a successful login
  IDService.reset();

  setup_test_identity(id, TEST_CERT, function() {
    // set it up so we're supposed to be logged in to TEST_URL

    get_idstore().setLoginState(TEST_URL, true, id);

    // When we authenticate, our ready callback will be fired.
    // At the same time, a separate topic will be sent up to the
    // the observer in the UI.  The test is complete when both
    // events have occurred.
    let mockedDoc = mock_doc(id, TEST_URL, call_sequentially(
      function(action, params) {
        do_check_eq(action, 'ready');
        do_check_eq(params, undefined);

        // if notification already received by observer, test is done
        callbacksFired = true;
        if (loginStateChanged && identityAuthComplete) {
          do_test_finished();
          run_next_test();
        }
      }
    ));

    makeObserver("identity-auth-complete", function(aSubject, aTopic, aData) {
      identityAuthComplete = true;
      do_test_finished();
      run_next_test();
    });

    makeObserver("identity-login-state-changed", function (aSubject, aTopic, aData) {
      do_check_neq(aSubject, null);

      do_check_eq(aSubject.wrappedJSObject.rpId, mockedDoc.id);
      do_check_eq(aData, id);

      // if callbacks in caller doc already fired, test is done.
      loginStateChanged = true;
      if (callbacksFired && identityAuthComplete) {
        do_test_finished();
        run_next_test();
      }
    });

    IDService.RP.watch(mockedDoc);

    // Create a provisioning flow for our auth flow to attach to
    setup_provisioning(
      TEST_USER,
      function(provFlow) {
        _provId = provFlow.id;

        IDService.IDP.beginProvisioning(provFlow);
      }, function() {},
      {
        beginProvisioningCallback: function(email, duration_s) {
          // let's say this user needs to authenticate
          IDService.IDP._doAuthentication(_provId, {idpParams:TEST_IDPPARAMS});

          // test_begin_authentication_flow verifies that the right
          // message is sent to the UI.  So that works.  Moving on,
          // the UI calls setAuthenticationFlow ...
          _authId = uuid();
          IDService.IDP.setAuthenticationFlow(_authId, _provId);

          // ... then the UI calls beginAuthentication ...
          authCaller.id = _authId;
          IDService.IDP._provisionFlows[_provId].caller = authCaller;
          IDService.IDP.beginAuthentication(authCaller);
        }
      }
    );
  });

  // A mock calling context
  let authCaller = {
    doBeginAuthenticationCallback: function doBeginAuthenticationCallback(identity) {
      do_check_eq(identity, TEST_USER);
      // completeAuthentication will emit "identity-auth-complete"
      IDService.IDP.completeAuthentication(_authId);
    },

    doError: function(err) {
      log("OW! My doError callback hurts!", err);
    },
  };

}

var TESTS = [];

TESTS.push(test_begin_authentication_flow);
TESTS.push(test_complete_authentication_flow);

TESTS.forEach(add_test);

function run_test() {
  run_next_test();
}