Search code examples
pythongoogle-admin-sdkgoogle-shared-contacts

Cannot Authorize my Service Account to use the Domain Shared contacts API


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 = (
        "[email protected]"
    )
    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('[email protected]')
        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="[email protected]",
                primary="true",
                rel=gdata.data.WORK_REL,
                display_name="E. Bennet",
            )
        )
        new_contact.email.append(
            gdata.data.Email(address="[email protected]", 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="[email protected]",
                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.


Solution

  • 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.