Sunday, 17 September 2023

Create Google Calendar invites using service account securely

I created a service account using my Enterprise Google Workspace account and I need to automate calendar invites creation using Python.

I have added the service account email into the calendar's shared people and when I try to get the calendar using service.calendarList().list().execute() it works fine.

However, if I try to send an invite it doesn't work, and I get the error below:

googleapiclient.errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/calendar/v3/calendars/xxxxxx%group.calendar.google.com/events?alt=json returned "You need to have writer access to this calendar.". Details: "[{'domain': 'calendar', 'reason': 'requiredAccessLevel', 'message': 'You need to have writer access to this calendar.'}]">

Looking at the docs I found that I need to delegate domain-wide authority to the service account for this to work, but my company isn't allowing this service account to have this type of access because of security issues.

So I wanted to know if there is any way that I could do this without delegating domain wide access to this service account ? Because delegating domain wide access gives me access to impersonated anyone in the domain, so it's a security issue. I want the service account to be able to impersonate just the parent google account from where it was created.

Below is the full code that I used to get the calendar and create the invite

from google.oauth2 import service_account
from googleapiclient.discovery import build


class GoogleCalendar:
    SCOPES = [
        "https://www.googleapis.com/auth/calendar",
        "https://www.googleapis.com/auth/calendar.events",
    ]

    def __init__(self, credentials, calendar_id) -> None:
        credentials = service_account.Credentials.from_service_account_file(
            credentials, scopes=self.SCOPES
        )
        self.service = build("calendar", "v3", credentials=credentials)
        self.id = calendar_id

    def get_calendar_list(self):
        return self.service.calendarList().list().execute()

    def add_calendar(self):
        entry = {"id": self.id}
        return self.service.calendarList().insert(body=entry).execute()

    def create_invite(self):
        event = {
            "summary": "Google I/O 2015",
            "location": "800 Howard St., San Francisco, CA 94103",
            "description": "A chance to hear more about Google's developer products.",
            "start": {
                "dateTime": "2023-09-16T09:00:00-07:00",
                "timeZone": "America/Los_Angeles",
            },
            "end": {
                "dateTime": "2023-09-16T17:00:00-07:00",
                "timeZone": "Indian/Mauritius",
            },
            "attendees": [{"email": "myemail@domain.com"}],
        }

        event = self.service.events().insert(calendarId=self.id, body=event).execute()

work_cal_id = "xxxxx@group.calendar.google.com"

cal = GoogleCalendar(
credentials="work.json", 
calendar_id=work_cal_id
)

cal.add_calendar()

print(cal.get_calendar_list())

cal.create_invite()


from Create Google Calendar invites using service account securely

No comments:

Post a Comment