Google-api-nodejs-client: How to setServiceAccountUser? Trying to use admin reports API and cannot.

Created on 3 Jul 2015  路  4Comments  路  Source: googleapis/google-api-nodejs-client

It seems that I need to specify the account to impersonate when making Admin Reports API calls because I'm getting "The API returned an error: Error: Access denied. You are not authorized to read activity records.". Everything I've found indicates that I need to call setServiceAccountUser() when building the call in other languages/libraries.

triage me

Most helpful comment

Yeah, this process is not described very well in the docs and isn't mentioned anywhere in the Node API package docs. In reference to the above, here's a quick example of making calls with a service account under an impersonated user:

var Promise = require( 'bluebird' );
var google  = require( 'googleapis' );
var path    = require( 'path' );
var key     = require( path.resolve( 'config/keys/bau-google.json' ) );

var jwtClient = new google.auth.JWT(
  key.client_email,
  null,
  key.private_key,
  [ 'https://www.googleapis.com/auth/calendar' ],
  '[email protected]'
);

function getCalendars () {
  return new Promise( function ( resolve, reject ) {
    jwtClient.authorize( function( err, tokens ) {
      if ( err ) {
        console.error( 'Unable to authenticate with google:', err );

        return reject( err );
      }

      // Create new calendar object from google API
      var calendar = google.calendar({
        version: 'v3',
        auth:    jwtClient
      });

      // And list user calendars
      calendar.calendarList.list( {}, function ( err, result ) {
        if ( err ) {
          console.error( 'Unable to retrieve user calendars:', err );

          return reject( err );
        }

        // And send back the response
        return resolve( result );
      });
    });
  });
}

All 4 comments

Looks like the impersonation account provided after scopes IS the way to go IF you need impersonation (don't provide it if you don't).

If you do need impersonation for a service account, visit the following as a domain admin to authorize a given service account for one or more scopes: https://admin.google.com/AdminHome?chromeless=1#OGX:ManageOauthClients

I found that information very hard to come by because the need isn't clearly addressed and the provided error doesn't lead to the appropriate documentation. In my case, it was available (if outdated) at https://developers.google.com/admin-sdk/reports/v1/guides/delegation

Yeah, this process is not described very well in the docs and isn't mentioned anywhere in the Node API package docs. In reference to the above, here's a quick example of making calls with a service account under an impersonated user:

var Promise = require( 'bluebird' );
var google  = require( 'googleapis' );
var path    = require( 'path' );
var key     = require( path.resolve( 'config/keys/bau-google.json' ) );

var jwtClient = new google.auth.JWT(
  key.client_email,
  null,
  key.private_key,
  [ 'https://www.googleapis.com/auth/calendar' ],
  '[email protected]'
);

function getCalendars () {
  return new Promise( function ( resolve, reject ) {
    jwtClient.authorize( function( err, tokens ) {
      if ( err ) {
        console.error( 'Unable to authenticate with google:', err );

        return reject( err );
      }

      // Create new calendar object from google API
      var calendar = google.calendar({
        version: 'v3',
        auth:    jwtClient
      });

      // And list user calendars
      calendar.calendarList.list( {}, function ( err, result ) {
        if ( err ) {
          console.error( 'Unable to retrieve user calendars:', err );

          return reject( err );
        }

        // And send back the response
        return resolve( result );
      });
    });
  });
}

Or using a JSON keyfile from your service account:

function impersonate(email){
var serviceAccount = new gal.JWT();
serviceAccount.fromJSON(json);
serviceAccount.subject = email;
serviceAccount.scopes = [
"https://www.googleapis.com/auth/admin.directory.user"
];
return serviceAccount;
}

(That's against the Directory, but same principle).

//auth
const jwtClient = new google.auth.JWT({
    email: key.client_email,
    key: key.private_key,
    scopes: SCOPES,
    subject: 'useremail@gsuite_domain.com'
});

The API returned an error: Error: unauthorized_client: Client is unauthorized to retrieve access tokens using this method.

@captainmisterhagan you might have any idea - pulling my hair out trying to find out how to do this

EDIT:::
I figured this out - subject should be delegationEmail, also change calendarid when doing you calendar.list

Was this page helpful?
0 / 5 - 0 ratings