import google.oauth2.credentials import google_auth_oauthlib.flow import googleapiclient.discovery import backend.caltojson as caltojson from oauthlib.oauth2 import WebApplicationClient import flask # Python standard libraries import json import os import sqlite3 # Third-party libraries import flask from flask import Flask, redirect, request, url_for from flask_login import ( LoginManager, current_user, login_required, login_user, logout_user, ) import requests from database.models import Calendar as dbCalendar # Configuration CLIENT_SECRETS_FILE = "certificate/client_secret.json" # This OAuth 2.0 access scope allows for full read/write access to the # authenticated user's account and requires requests to use an SSL connection. SCOPES = ["https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/calendar.readonly", "openid"] API_SERVICE_NAME = 'calendar' API_VERSION = 'v3' GOOGLE_CLIENT_ID ="377787187748-shuvi4iq5bi4gdet6q3ioataimobs4lh.apps.googleusercontent.com" GOOGLE_CLIENT_SECRET = "Hu_YWmKsVKUcLwyeINYzdKfZ" GOOGLE_DISCOVERY_URL = ( "https://accounts.google.com/.well-known/openid-configuration" ) # OAuth 2 client setup client = WebApplicationClient(GOOGLE_CLIENT_ID) def login(): # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps. flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( CLIENT_SECRETS_FILE, scopes=SCOPES) # The URI created here must exactly match one of the authorized redirect URIs # for the OAuth 2.0 client, which you configured in the API Console. If this # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch' # error. flow.redirect_uri = request.base_url + "/callback" authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true') # Store the state so the callback can verify the auth server response. flask.session['state'] = state # Flask-Login helper to retrieve a user from our db return authorization_url def verifyResponse(): # Specify the state when creating the flow in the callback so that it can # verified in the authorization server response. state = flask.session['state'] flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( CLIENT_SECRETS_FILE, scopes=SCOPES, state=state) flow.redirect_uri = flask.url_for('callback', _external=True) # Use the authorization server's response to fetch the OAuth 2.0 tokens. authorization_response = flask.request.url flow.fetch_token(authorization_response=authorization_response) # Store credentials in the session. # ACTION ITEM: In a production app, you likely want to save these # credentials in a persistent database instead. credentials = flow.credentials flask.session['credentials'] = credentials_to_dict(credentials) print(credentials_to_dict(credentials), flush=True) session = flow.authorized_session() return session, credentials_to_dict(credentials) def get_google_provider_cfg(): return requests.get(GOOGLE_DISCOVERY_URL).json() def deleteAccount(user): result = requests.post('https://oauth2.googleapis.com/revoke', params={'token': user.get('token')}, headers = {'content-type': 'applixation/x-www-form-urlencoded'}) print(result, flush=True) return class Calendar: def __init__(self, name, calendarId, toggle='False', color="#000000"): self.name = name self.color = color self.toggle=toggle self.calendarId = calendarId def calendarsFromDb(): calendars = dbCalendar.getCalendars(dbCalendar, current_user.id) pyCalendars = [] for calendar in calendars: name = (calendar.name[:16] + '..') if len(calendar.name)> 18 else calendar.name calendarId = calendar.calendar_id toggle = calendar.toggle color = calendar.color pyCalendars.append(Calendar(name, calendarId, toggle, color)) return pyCalendars def getCalendarJson(): if 'credentials' not in flask.session: return flask.redirect('login/google') # Load credentials from the session. credentials = google.oauth2.credentials.Credentials( **flask.session['credentials']) with open('./userinfo/' + current_user.id + '/calendarevents.json', 'w') as outfile: json.dump(todaysCal, outfile) return todaysCal def updateCalendars(): if 'credentials' not in flask.session: return flask.redirect('login/google') # Load credentials from the session. # credentials = google.oauth2.credentials.Credentials( # **flask.session['credentials']) # a = flask.session['credentials'] # print(a, flush=True) # print(current_user.getGoogleCredentials(), flush=True) if current_user.getGoogleCredentials() == None: return credentials = google.oauth2.credentials.Credentials(**current_user.getGoogleCredentials()) calendars = caltojson.getCalendarList(credentials) for calendar in calendars: if dbCalendar.getCalendar(dbCalendar, current_user.id, calendar.calendarId) == None: dbCalendar.create(dbCalendar, current_user.id, calendar.calendarId, calendar.summary, calendar.color) print("updated Calendars") # Save credentials back to session in case access token was refreshed. # ACTION ITEM: In a production app, you likely want to save these # credentials in a persistent database instead. flask.session['credentials'] = credentials_to_dict(credentials) def credentials_to_dict(credentials): return {'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, 'scopes': credentials.scopes}