tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_tokenserverclient.js (11095B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 const {
      5  TokenServerClient,
      6  TokenServerClientError,
      7  TokenServerClientServerError,
      8 } = ChromeUtils.importESModule(
      9  "resource://services-common/tokenserverclient.sys.mjs"
     10 );
     11 
     12 initTestLogging("Trace");
     13 
     14 add_task(async function test_working_token_exchange() {
     15  _("Ensure that working OAuth token exchange works as expected.");
     16 
     17  let service = "http://example.com/foo";
     18  let duration = 300;
     19 
     20  let server = httpd_setup({
     21    "/1.0/foo/1.0": function (request, response) {
     22      Assert.ok(request.hasHeader("accept"));
     23      Assert.equal("application/json", request.getHeader("accept"));
     24 
     25      response.setStatusLine(request.httpVersion, 200, "OK");
     26      response.setHeader("Content-Type", "application/json");
     27 
     28      let body = JSON.stringify({
     29        id: "id",
     30        key: "key",
     31        api_endpoint: service,
     32        uid: "uid",
     33        duration,
     34      });
     35      response.bodyOutputStream.write(body, body.length);
     36    },
     37  });
     38 
     39  let client = new TokenServerClient();
     40  let url = server.baseURI + "/1.0/foo/1.0";
     41  let result = await client.getTokenUsingOAuth(url, "access_token");
     42  Assert.equal("object", typeof result);
     43  do_check_attribute_count(result, 7);
     44  Assert.equal(service, result.endpoint);
     45  Assert.equal("id", result.id);
     46  Assert.equal("key", result.key);
     47  Assert.equal("uid", result.uid);
     48  Assert.equal(duration, result.duration);
     49  Assert.deepEqual(undefined, result.node_type);
     50  await promiseStopServer(server);
     51 });
     52 
     53 add_task(async function test_working_token_exchange_with_nodetype() {
     54  _("Ensure that a token response with a node type as expected.");
     55 
     56  let service = "http://example.com/foo";
     57  let duration = 300;
     58  let nodeType = "the-node-type";
     59 
     60  let server = httpd_setup({
     61    "/1.0/foo/1.0": function (request, response) {
     62      Assert.ok(request.hasHeader("accept"));
     63      Assert.equal("application/json", request.getHeader("accept"));
     64 
     65      response.setStatusLine(request.httpVersion, 200, "OK");
     66      response.setHeader("Content-Type", "application/json");
     67 
     68      let body = JSON.stringify({
     69        id: "id",
     70        key: "key",
     71        api_endpoint: service,
     72        uid: "uid",
     73        duration,
     74        node_type: nodeType,
     75      });
     76      response.bodyOutputStream.write(body, body.length);
     77    },
     78  });
     79 
     80  let client = new TokenServerClient();
     81  let url = server.baseURI + "/1.0/foo/1.0";
     82  let result = await client.getTokenUsingOAuth(url, "access_token");
     83  Assert.equal("object", typeof result);
     84  do_check_attribute_count(result, 7);
     85  Assert.equal(service, result.endpoint);
     86  Assert.equal("id", result.id);
     87  Assert.equal("key", result.key);
     88  Assert.equal("uid", result.uid);
     89  Assert.equal(duration, result.duration);
     90  Assert.equal(nodeType, result.node_type);
     91  await promiseStopServer(server);
     92 });
     93 
     94 add_task(async function test_invalid_arguments() {
     95  _("Ensure invalid arguments to APIs are rejected.");
     96 
     97  let args = [
     98    [null, "access_token"],
     99    ["http://example.com/", null],
    100  ];
    101 
    102  for (let arg of args) {
    103    let client = new TokenServerClient();
    104    await Assert.rejects(client.getTokenUsingOAuth(arg[0], arg[1]), ex => {
    105      Assert.ok(ex instanceof TokenServerClientError);
    106      return true;
    107    });
    108  }
    109 });
    110 
    111 add_task(async function test_invalid_403_no_content_type() {
    112  _("Ensure that a 403 without content-type is handled properly.");
    113 
    114  let server = httpd_setup({
    115    "/1.0/foo/1.0": function (request, response) {
    116      response.setStatusLine(request.httpVersion, 403, "Forbidden");
    117      // No Content-Type header by design.
    118 
    119      let body = JSON.stringify({
    120        errors: [{ description: "irrelevant", location: "body", name: "" }],
    121        urls: { foo: "http://bar" },
    122      });
    123      response.bodyOutputStream.write(body, body.length);
    124    },
    125  });
    126 
    127  let client = new TokenServerClient();
    128  let url = server.baseURI + "/1.0/foo/1.0";
    129 
    130  await Assert.rejects(
    131    client.getTokenUsingOAuth(url, "access_token"),
    132    error => {
    133      Assert.ok(error instanceof TokenServerClientServerError);
    134      Assert.equal(error.cause, "malformed-response");
    135 
    136      Assert.equal(null, error.urls);
    137      return true;
    138    }
    139  );
    140 
    141  await promiseStopServer(server);
    142 });
    143 
    144 add_task(async function test_send_extra_headers() {
    145  _("Ensures that the condition acceptance header is sent when asked.");
    146 
    147  let duration = 300;
    148  let server = httpd_setup({
    149    "/1.0/foo/1.0": function (request, response) {
    150      Assert.ok(request.hasHeader("x-foo"));
    151      Assert.equal(request.getHeader("x-foo"), "42");
    152 
    153      Assert.ok(request.hasHeader("x-bar"));
    154      Assert.equal(request.getHeader("x-bar"), "17");
    155 
    156      response.setStatusLine(request.httpVersion, 200, "OK");
    157      response.setHeader("Content-Type", "application/json");
    158 
    159      let body = JSON.stringify({
    160        id: "id",
    161        key: "key",
    162        api_endpoint: "http://example.com/",
    163        uid: "uid",
    164        duration,
    165      });
    166      response.bodyOutputStream.write(body, body.length);
    167    },
    168  });
    169 
    170  let client = new TokenServerClient();
    171  let url = server.baseURI + "/1.0/foo/1.0";
    172 
    173  let extra = {
    174    "X-Foo": 42,
    175    "X-Bar": 17,
    176  };
    177 
    178  await client.getTokenUsingOAuth(url, "access_token", extra);
    179  // Other tests validate other things.
    180 
    181  await promiseStopServer(server);
    182 });
    183 
    184 add_task(async function test_error_404_empty() {
    185  _("Ensure that 404 responses without proper response are handled properly.");
    186 
    187  let server = httpd_setup();
    188 
    189  let client = new TokenServerClient();
    190  let url = server.baseURI + "/foo";
    191 
    192  await Assert.rejects(
    193    client.getTokenUsingOAuth(url, "access_token"),
    194    error => {
    195      Assert.ok(error instanceof TokenServerClientServerError);
    196      Assert.equal(error.cause, "malformed-response");
    197 
    198      Assert.notEqual(null, error.response);
    199      return true;
    200    }
    201  );
    202 
    203  await promiseStopServer(server);
    204 });
    205 
    206 add_task(async function test_error_404_proper_response() {
    207  _("Ensure that a Cornice error report for 404 is handled properly.");
    208 
    209  let server = httpd_setup({
    210    "/1.0/foo/1.0": function (request, response) {
    211      response.setStatusLine(request.httpVersion, 404, "Not Found");
    212      response.setHeader("Content-Type", "application/json; charset=utf-8");
    213 
    214      let body = JSON.stringify({
    215        status: 404,
    216        errors: [{ description: "No service", location: "body", name: "" }],
    217      });
    218 
    219      response.bodyOutputStream.write(body, body.length);
    220    },
    221  });
    222 
    223  let client = new TokenServerClient();
    224  let url = server.baseURI + "/1.0/foo/1.0";
    225 
    226  await Assert.rejects(
    227    client.getTokenUsingOAuth(url, "access_token"),
    228    error => {
    229      Assert.ok(error instanceof TokenServerClientServerError);
    230      Assert.equal(error.cause, "unknown-service");
    231      return true;
    232    }
    233  );
    234 
    235  await promiseStopServer(server);
    236 });
    237 
    238 add_task(async function test_bad_json() {
    239  _("Ensure that malformed JSON is handled properly.");
    240 
    241  let server = httpd_setup({
    242    "/1.0/foo/1.0": function (request, response) {
    243      response.setStatusLine(request.httpVersion, 200, "OK");
    244      response.setHeader("Content-Type", "application/json");
    245 
    246      let body = '{"id": "id", baz}';
    247      response.bodyOutputStream.write(body, body.length);
    248    },
    249  });
    250 
    251  let client = new TokenServerClient();
    252  let url = server.baseURI + "/1.0/foo/1.0";
    253 
    254  await Assert.rejects(
    255    client.getTokenUsingOAuth(url, "access_token"),
    256    error => {
    257      Assert.notEqual(null, error);
    258      Assert.equal("TokenServerClientServerError", error.name);
    259      Assert.equal(error.cause, "malformed-response");
    260      Assert.notEqual(null, error.response);
    261      return true;
    262    }
    263  );
    264 
    265  await promiseStopServer(server);
    266 });
    267 
    268 add_task(async function test_400_response() {
    269  _("Ensure HTTP 400 is converted to malformed-request.");
    270 
    271  let server = httpd_setup({
    272    "/1.0/foo/1.0": function (request, response) {
    273      response.setStatusLine(request.httpVersion, 400, "Bad Request");
    274      response.setHeader("Content-Type", "application/json; charset=utf-8");
    275 
    276      let body = "{}"; // Actual content may not be used.
    277      response.bodyOutputStream.write(body, body.length);
    278    },
    279  });
    280 
    281  let client = new TokenServerClient();
    282  let url = server.baseURI + "/1.0/foo/1.0";
    283 
    284  await Assert.rejects(
    285    client.getTokenUsingOAuth(url, "access_token"),
    286    error => {
    287      Assert.notEqual(null, error);
    288      Assert.equal("TokenServerClientServerError", error.name);
    289      Assert.notEqual(null, error.response);
    290      Assert.equal(error.cause, "malformed-request");
    291      return true;
    292    }
    293  );
    294 
    295  await promiseStopServer(server);
    296 });
    297 
    298 add_task(async function test_401_with_error_cause() {
    299  _("Ensure 401 cause is specified in body.status");
    300 
    301  let server = httpd_setup({
    302    "/1.0/foo/1.0": function (request, response) {
    303      response.setStatusLine(request.httpVersion, 401, "Unauthorized");
    304      response.setHeader("Content-Type", "application/json; charset=utf-8");
    305 
    306      let body = JSON.stringify({ status: "no-soup-for-you" });
    307      response.bodyOutputStream.write(body, body.length);
    308    },
    309  });
    310 
    311  let client = new TokenServerClient();
    312  let url = server.baseURI + "/1.0/foo/1.0";
    313 
    314  await Assert.rejects(
    315    client.getTokenUsingOAuth(url, "access_token"),
    316    error => {
    317      Assert.notEqual(null, error);
    318      Assert.equal("TokenServerClientServerError", error.name);
    319      Assert.notEqual(null, error.response);
    320      Assert.equal(error.cause, "no-soup-for-you");
    321      return true;
    322    }
    323  );
    324 
    325  await promiseStopServer(server);
    326 });
    327 
    328 add_task(async function test_unhandled_media_type() {
    329  _("Ensure that unhandled media types throw an error.");
    330 
    331  let server = httpd_setup({
    332    "/1.0/foo/1.0": function (request, response) {
    333      response.setStatusLine(request.httpVersion, 200, "OK");
    334      response.setHeader("Content-Type", "text/plain");
    335 
    336      let body = "hello, world";
    337      response.bodyOutputStream.write(body, body.length);
    338    },
    339  });
    340 
    341  let url = server.baseURI + "/1.0/foo/1.0";
    342  let client = new TokenServerClient();
    343 
    344  await Assert.rejects(
    345    client.getTokenUsingOAuth(url, "access_token"),
    346    error => {
    347      Assert.notEqual(null, error);
    348      Assert.equal("TokenServerClientServerError", error.name);
    349      Assert.notEqual(null, error.response);
    350      return true;
    351    }
    352  );
    353 
    354  await promiseStopServer(server);
    355 });
    356 
    357 add_task(async function test_rich_media_types() {
    358  _("Ensure that extra tokens in the media type aren't rejected.");
    359 
    360  let duration = 300;
    361  let server = httpd_setup({
    362    "/foo": function (request, response) {
    363      response.setStatusLine(request.httpVersion, 200, "OK");
    364      response.setHeader("Content-Type", "application/json; foo=bar; bar=foo");
    365 
    366      let body = JSON.stringify({
    367        id: "id",
    368        key: "key",
    369        api_endpoint: "foo",
    370        uid: "uid",
    371        duration,
    372      });
    373      response.bodyOutputStream.write(body, body.length);
    374    },
    375  });
    376 
    377  let url = server.baseURI + "/foo";
    378  let client = new TokenServerClient();
    379 
    380  await client.getTokenUsingOAuth(url, "access_token");
    381  await promiseStopServer(server);
    382 });