<commit_before>const taskcluster = require('taskcluster-client');
const scopeUtils = require('taskcluster-lib-scopes');
const {CLIENT_ID_PATTERN} = require('./utils');
const Debug = require('debug');

const debug = Debug('scanner');

async function scanner(cfg, handlers) {
  // * get the set of identityProviderIds
  // * for each:
  //   * fetch all clients
  //   * for each identity:
  //     * get roles from providers, expand
  //     * for each client in that identity:
  //       * get, verify client.expandedScopes satisfied by identity's expandedScopes

  // NOTE: this function performs once auth operation at a time.  It is better
  // for scans to take longer than for the auth service to be overloaded.
  let auth = new taskcluster.Auth({credentials: cfg.app.credentials});

  const scan = async h => {
    const handler = handlers[h];
    const clients = await auth.listClients({prefix: `${handler.identityProviderId}/`});

    // iterate through the clients, constructing a new User as necessary, comparing
    // the client's scopes to the User's scopes and disabling where necessary.
    let user, userScopes;

    for (let client of clients) {
      debug('examining client', client.clientId);
      if (!client.clientId.match(CLIENT_ID_PATTERN) || client.disabled) {
        continue;
      }

      if (!user || user.identity !== handler.identityFromClientId(client.clientId)) {
        user = await handler.userFromClientId(client.clientId);

        if (!user) {
          continue;
        }

        userScopes = (await auth.expandScopes({scopes: user.scopes()})).scopes;
<commit_msg>compatibility with listClients API (#95)<commit_after>const taskcluster = require('taskcluster-client');
const scopeUtils = require('taskcluster-lib-scopes');
const {CLIENT_ID_PATTERN} = require('./utils');
const Debug = require('debug');
const _ = require('lodash');

const debug = Debug('scanner');

async function scanner(cfg, handlers) {
  // * get the set of identityProviderIds
  // * for each:
  //   * fetch all clients
  //   * for each identity:
  //     * get roles from providers, expand
  //     * for each client in that identity:
  //       * get, verify client.expandedScopes satisfied by identity's expandedScopes

  // NOTE: this function performs once auth operation at a time.  It is better
  // for scans to take longer than for the auth service to be overloaded.
  let auth = new taskcluster.Auth({credentials: cfg.app.credentials});

  const scan = async h => {
    const handler = handlers[h];
    const clientResponse = await auth.listClients({prefix: `${handler.identityProviderId}/`});
    const clients = _.get(clientResponse, 'clients', clientResponse);

    // iterate through the clients, constructing a new User as necessary, comparing
    // the client's scopes to the User's scopes and disabling where necessary.
    let user, userScopes;

    for (let client of clients) {
      debug('examining client', client.clientId);
      if (!client.clientId.match(CLIENT_ID_PATTERN) || client.disabled) {
        continue;
      }

      if (!user || user.identity !== handler.identityFromClientId(client.clientId)) {
        user = await handler.userFromClientId(client.clientId);

        if (!user) {
          continue;
        }

        userScopes = (await auth.expandScopes({scopes: user.scopes()})).scopes;

{'fraction_non_alphanumeric': 0.11638316920322292, 'fraction_numerical': 0.000596836765144733, 'mean_word_length': 3.2755102040816326, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6561722', 'n_tokens_mistral': 953, 'n_tokens_neox': 918, 'n_words': 299}