0

I'm trying to impersonate a super admin account to use the shared contacts API to create new contacts in a directory, after using the gdata client library I couldn't authorize my request even tho I used the same method I used to authorize another API call but for the Directory API instead of the Domain Shared Contacts.

Here is my code:

from googleapiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
import gdata.contacts
import gdata.contacts.data
import gdata.contacts.client
import atom

class TestView(APIView):

    SERVICE_ACCOUNT_EMAIL = (
        "x-serviceaccount@x.iam.gserviceaccount.com"
    )
    SERVICE_ACCOUNT_PKCS12_FILE_PATH = "C:\\Users\\Hoda\\Desktop\\xtools\\x\\Backend\\x-x.p12"

    def get(self, request, *args, **kwargs):

        credentials = ServiceAccountCredentials.from_p12_keyfile(
            self.SERVICE_ACCOUNT_EMAIL,
            self.SERVICE_ACCOUNT_PKCS12_FILE_PATH,
            "notasecret",
            scopes=[
                'https://www.googleapis.com/auth/admin.directory.user',
                'https://www.googleapis.com/auth/admin.directory.user.security',
                'https://www.googleapis.com/auth/admin.directory.group',
                'https://www.google.com/m8/feeds/contacts/'
            ],
        )

        gd_client = gdata.contacts.client.ContactsClient()
        credentials = credentials.create_delegated('admin@admin.com')
        service = build('admin', 'something', credentials=credentials) 
        #while using the directory API I wrote directory_v1 instead of 
        #something and now I have no 
        #idea what to write and is that even the right way to authorize 
        #the service account here or not

        new_contact = gdata.contacts.data.ContactEntry()
        new_contact.name = gdata.data.Name(
            given_name=gdata.data.GivenName(text="Mohamed"),
            family_name=gdata.data.FamilyName(text="Safi"),
            full_name=gdata.data.FullName(text="Mohamed Safi"),
        )
        new_contact.content = atom.data.Content(text="Notes")
        new_contact.email.append(
            gdata.data.Email(
                address="liz@gmail.com",
                primary="true",
                rel=gdata.data.WORK_REL,
                display_name="E. Bennet",
            )
        )
        new_contact.email.append(
            gdata.data.Email(address="liz@example.com", rel=gdata.data.HOME_REL)
        )
        new_contact.phone_number.append(
            gdata.data.PhoneNumber(
                text="(206)555-1212", rel=gdata.data.WORK_REL, primary="true"
            )
        )
        new_contact.phone_number.append(
            gdata.data.PhoneNumber(text="(206)555-1213", rel=gdata.data.HOME_REL)
        )
        new_contact.im.append(
            gdata.data.Im(
                text="liz@gmail.com",
                primary="true",
                rel=gdata.data.HOME_REL,
                protocol=gdata.data.GOOGLE_TALK_PROTOCOL,
            )
        )
        new_contact.structured_postal_address.append(
            gdata.data.PostalAddress(
            rel=gdata.data.WORK_REL,
            primary="true",
            street=gdata.data.Street(text="1600 Amphitheatre Pkwy"),
            city=gdata.data.City(text="Mountain View"),
            region=gdata.data.Region(text="CA"),
            postcode=gdata.data.Postcode(text="94043"),
            country=gdata.data.Country(text="United States"),)
        )
        contact_entry = gd_client.create_contact(new_contact) 
        print("Contact's ID: %s" % contact_entry.id.text)
        return Response(contact_entry)

So, now I just want to know how to authorize that service account to write data into my directory.

side note: I have given the service account all the authorization needed in my admin console.

Sunderam Dubey
  • 1
  • 11
  • 20
  • 40
Ahmad Othman
  • 853
  • 5
  • 18
  • Are there any error codes or identifiers as to where the authorization is failing? Maybe we can start from there – Century Tuna Dec 20 '21 at 19:58
  • no there aren't any errors in my code, just not authorized to create a user. 403 error that is what I get – Ahmad Othman Dec 20 '21 at 21:26
  • if only there is a way to know what is the service name and version to use the `build` function from `googleapiclient.discovery`, I think that will solve the issue – Ahmad Othman Dec 20 '21 at 21:28
  • It might be best if you could read through this [documentation](https://developers.google.com/admin-sdk/domain-shared-contacts) – Century Tuna Dec 21 '21 at 16:04

1 Answers1

0

I found out that using the discovery build function is not the right way to call the create_contact() function which is associated with the domain shared contacts API. What I found out is that I can authorize my service account using the gauth module which lies inside the gdata library, you can import it as follows:

import gdata.gauth

after that,

  1. you create your service account credentials the same way as shown in the question code.
  2. use the OAuth2TokenFromCredentials class which lies inside the gauth module to provide a way for you to use OAuth 2.0 credentials obtained for use with google-api-python-client as credentials in gdata-python-client, you can use it as follows: auth2token = gdata.gauth.OAuth2TokenFromCredentials(credentials)

credentials in the code above refer to the credentials you just created using your service account email and key file.

  1. authorize your gdata client gd_client = auth2token.authorize(gd_client)

then after that, congrats you can use your gdata client to make authorized requests with your service account impersonating any admin at any workspace.

Ahmad Othman
  • 853
  • 5
  • 18