0

I have been trying to get emails from another user in my domail in order to migrate it, using the google nodejs library. My account is superadmin and my API has wide-domain delegation permission enable with the following scopes:

"https://www.googleapis.com/auth/apps.groups.migration",
"https://mail.google.com/",
"https://www.googleapis.com/auth/gmail.settings.sharing"

I have logged into the API usin an impersonate access

async function initializeGmail(emailToImpersonate) {
        const auth = await getAuth(emailToImpersonate);
        return google.gmail({
            version: 'v1',
            auth
        });
    }

    async function getAuth(emailToImpersonate) {
        const jwtClient = new google.auth.JWT(
            client_email,
            null,
            private_key,
            SCOPES,
            emailToImpersonate
        );
        await jwtClient.authorize();
        return jwtClient;
    }

I have added delegation permitions in the account I want to migrate so I can access its emails from my main account

const requestBody = {
        delegateEmail: user.email,
        verificationStatus: 'accepted'
}
await gmail.users.settings.delegates.create({userId, requestBody})

I request the emails of the account to migrate and I get the following error

const gmail = await initializeGmail(userEmail);
const messages =  (await gmail.users.messages.list({auth, userId:userEmail})).data.messages;
code: 403,
errors: [
    {
      domain: 'global',
      reason: 'forbidden',
      message: 'Delegation denied for sysadmin@boatjump.com'
    }
]

Any help or ideas will be highly appreciated

Raul Gomez
  • 11
  • 1
  • 3

1 Answers1

0

1st step - Create a delegate

  • To create a delegate, the parameter delegateEmail must specify the primary email of the delegate, that is your main account, I assume sysadmin@boatjump.com
  • As specified in the documentation, the delegate creation must performed by a service account that impersonates the delegator (your secondary account, I assume user.email)

2nd step - list the delegator's emails

  • Authenticate as sysadmin@boatjump.co' (no need for service account)
  • Specify as userId user.email

The reason you obtained a 403 error is the fact you specified user.email instead of sysadmin@boatjump.com as the delegate and thus did not pass to sysadmin@boatjump.com the authority to list user.email's emails.

UPDATE:

If after a correct set-up of a delegate you continue experiencing issues with retrieving the delegator's emails, this issue is likely related to this behavior already reported on Google's Issue Tracker.

I recommend you to give it a "star" to increase visibility and the chances that it will be fixed in the future.

Workaround for the meantime:

When using the service account with domain-wide delegation, authenticate as the delegator and retrieve the emails on his behalf (userId:"me").

ziganotschka
  • 25,866
  • 2
  • 16
  • 33
  • It's possible that I have explained myself wrong but my main gmail's account is user.email and the accoutn that I want to delegate is userEmail – Raul Gomez May 15 '20 at 16:11
  • What is then sysadmin@boatjump.com? – ziganotschka May 16 '20 at 10:19
  • user.email = sysadmin, userEmail = email that I want to migrate – Raul Gomez May 17 '20 at 11:09
  • And `emailToImpersonate`is the same like `userEmail`? What about `userId` in `gmail.users.settings.delegates.create({userId, requestBody})`? – ziganotschka May 17 '20 at 12:48
  • Yes emailToImpersonate is the same that userEmail and userId is the ID of the userEmail – Raul Gomez May 18 '20 at 09:46
  • The issue seems related to the fact that you do not authenticate a as the service account `gmail = google.gmail({version: 'v1', auth: jwtClient });` when performing the request `gmail.users.settings.delegates.create({userId, requestBody})`, so your request is not succesful. I recommend you to list delegates for `emailToImpersonate` to verify that the creation of delegates has been performed succesfully. Also, `verificationStatus: 'accepted'` is a readonly value, do no specify it in your resource body. – ziganotschka May 18 '20 at 11:12
  • I use this lane `(await gmail.users.settings.delegates.list({userId})).data.delegates` And my response is `[ { delegateEmail: 'sysadmin@boatjump.com', verificationStatus: 'accepted' } ]` – Raul Gomez May 19 '20 at 10:11
  • And to retrieve the emails, why do you define `const gmail = await initializeGmail(userEmail);` - that is you do not identify as `sysadmin@boatjump.com`? Try to retrieve the emails without service account, auhtenticated with the crendetials of `sysadmin@boatjump.com`, something like `const gmail = google.gmail({version: 'v1', auth}); gmail.users.labels.list({ userId: 'me', }, (err, res) => {...`. A reason for your problem is that you seem to use promises, which is [not supported by googleapsis](https://stackoverflow.com/questions/47400116/nodejs-gmail-api-not-supporting-promises) – ziganotschka May 19 '20 at 11:01
  • but If I use to read emails `userId:'me'` I will read my emails and I want to read the emails of the other account. – Raul Gomez May 19 '20 at 14:12
  • Excuse me, I meant `const gmail = google.gmail({version: 'v1', auth}); gmail.users.labels.list({ userId: userEmail, }, (err, res) => {...` – ziganotschka May 19 '20 at 14:28
  • I have the same problem. res values is undefined and err values is `errors: [ { domain: 'global', reason: 'forbidden', message: 'Delegation denied for sysadmin@boatjump.com' } ]` – Raul Gomez May 20 '20 at 10:12
  • And both emails are Gmail / GSuite accounts? – ziganotschka May 20 '20 at 10:15
  • Yes and the two stay in the same company. – Raul Gomez May 20 '20 at 16:53
  • 1
    I found a [bug](https://issuetracker.google.com/36760064) on Google's Issue Tracker that is related to your issue! I initially assumed that your issue is due to erroneous delegation, but if your delegation is successful, your permission error msut be related to the bug. I will update my answer. – ziganotschka May 21 '20 at 10:51