Skip to content

Commit

Permalink
feat: update google oauth for google calendar integration
Browse files Browse the repository at this point in the history
  • Loading branch information
theofficialvedantjoshi committed Jan 8, 2025
1 parent 8c27331 commit 11a50bf
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 34 deletions.
68 changes: 52 additions & 16 deletions zulip/integrations/google/get-google-credentials
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,43 @@
import argparse
import os

from oauth2client import client, tools
from oauth2client.file import Storage
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow # type: ignore[import-untyped]

parser = argparse.ArgumentParser(add_help=False)
parser.add_argument(
"--auth_host_name", default="localhost", help="Hostname when running a local web server."
)
parser.add_argument(
"--noauth_local_webserver",
action="store_true",
default=False,
help="Do not run a local web server.",
)
parser.add_argument(
"--auth_host_port",
default=[8080, 8090],
type=int,
nargs="*",
help="Port web server should listen on.",
)
flags = parser.parse_args()

flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()

# If modifying these scopes, delete your previously saved credentials
# at zulip/bots/gcal/
# NOTE: When adding more scopes, add them after the previous one in the same field, with a space
# seperating them.
SCOPES = "https://www.googleapis.com/auth/calendar.readonly"
SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"]
# This file contains the information that google uses to figure out which application is requesting
# this client's data.
CLIENT_SECRET_FILE = "client_secret.json" # noqa: S105
APPLICATION_NAME = "Zulip Calendar Bot"
HOME_DIR = os.path.expanduser("~")


def get_credentials() -> client.Credentials:
def get_credentials() -> Credentials:
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
Expand All @@ -28,19 +47,36 @@ def get_credentials() -> client.Credentials:
Returns:
Credentials, the obtained credential.
"""

credentials = None
credential_path = os.path.join(HOME_DIR, "google-credentials.json")

store = Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(os.path.join(HOME_DIR, CLIENT_SECRET_FILE), SCOPES)
flow.user_agent = APPLICATION_NAME
# This attempts to open an authorization page in the default web browser, and asks the user
# to grant the bot access to their data. If the user grants permission, the run_flow()
# function returns new credentials.
credentials = tools.run_flow(flow, store, flags)
if os.path.exists(credential_path):
credentials = Credentials.from_authorized_user_file(credential_path, SCOPES)
if not credentials or not credentials.valid:
if credentials and credentials.expired and credentials.refresh_token:
credentials.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
os.path.join(HOME_DIR, CLIENT_SECRET_FILE), SCOPES
)
if not flags.noauth_local_webserver:
credentials = flow.run_local_server(
host=flags.auth_host_name, port=flags.auth_host_port[0]
)
# This attempts to open an authorization page in the default web browser, and asks the user
# to grant the bot access to their data. If the user grants permission, the run_flow()
# function returns new credentials.
else:
auth_url, _ = flow.authorization_url(prompt="consent")
print(
"Proceed to the following link in your browser:",
auth_url,
)
auth_code = input("Enter the authorization code: ")
credentials = flow.fetch_token(code=auth_code)
with open(credential_path, "w") as token:
token.write(credentials.to_json())
print("Storing credentials to " + credential_path)
return credentials


get_credentials()
27 changes: 11 additions & 16 deletions zulip/integrations/google/google-calendar
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,18 @@ import time
from typing import List, Optional, Set, Tuple

import dateutil.parser
import httplib2
import pytz
from oauth2client import client
from oauth2client.file import Storage

try:
from googleapiclient import discovery
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
except ImportError:
logging.exception("Install google-api-python-client")
logging.exception("Install google-api-python-client and google-auth-oauthlib")
sys.exit(1)

sys.path.append(os.path.join(os.path.dirname(__file__), "../../"))
import zulip

SCOPES = "https://www.googleapis.com/auth/calendar.readonly"
SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"]
CLIENT_SECRET_FILE = "client_secret.json" # noqa: S105
APPLICATION_NAME = "Zulip"
HOME_DIR = os.path.expanduser("~")
Expand Down Expand Up @@ -88,7 +85,7 @@ if not options.zulip_email:
zulip_client = zulip.init_from_options(options)


def get_credentials() -> client.Credentials:
def get_credentials() -> Credentials:
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
Expand All @@ -100,22 +97,20 @@ def get_credentials() -> client.Credentials:
"""
try:
credential_path = os.path.join(HOME_DIR, "google-credentials.json")

store = Storage(credential_path)
return store.get()
except client.Error:
credentials = Credentials.from_authorized_user_file(credential_path, SCOPES)
except ValueError:
logging.exception("Error while trying to open the `google-credentials.json` file.")
sys.exit(1)
except OSError:
logging.error("Run the get-google-credentials script from this directory first.")
sys.exit(1)
else:
return credentials


def populate_events() -> Optional[None]:
credentials = get_credentials()
creds = credentials.authorize(httplib2.Http())
service = discovery.build("calendar", "v3", http=creds)

creds = get_credentials()
service = build("calendar", "v3", credentials=creds)
now = datetime.datetime.now(pytz.utc).isoformat()
feed = (
service.events()
Expand Down
5 changes: 3 additions & 2 deletions zulip/integrations/google/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
httplib2>=0.22.0
oauth2client>=4.1.3
google-api-python-client>=2.157.0
google-auth-httplib2>=0.2.0
google-auth-oauthlib>=1.2.1

0 comments on commit 11a50bf

Please sign in to comment.