Example #1
0
def doauth():
    print('in /doauth')

    client_config_str = os.getenv('GOOGLE_CLIENT_SECRETS', None)
    if client_config_str:
        client_config = json.loads(client_config_str)
        flow = Flow.from_client_config(client_config=client_config,
                                       scopes=SCOPES)
    else:
        # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
        flow = Flow.from_client_secrets_file(CLIENT_SECRET_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 = url_for('auth', _scheme='https', _external=True)
    if 'localhost' in flow.redirect_uri:
        flow.redirect_uri = url_for('auth', _scheme='http', _external=True)

    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.
    session['state'] = state

    return redirect(authorization_url)
Example #2
0
def load_calendar(request):
    # here call method load calendar
    # print(request.user)  # current user
    # obtain calendar token
    creds = CalendarCredentials.objects.filter(student=request.user)
    creds = pickle.loads(creds[0].credentials) if creds else None
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            try:
                creds.refresh(Request())
            except:
                try:
                    flow = Flow.from_client_config(
                        json.loads(os.environ["CLIENT_CONFIG"]), SCOPES)
                    flow.redirect_uri = (
                        "https://schedme.osc-fr1.scalingo.io/students/callback"
                    )
                    authorization_url, state = flow.authorization_url(
                        access_type="offline")
                    return redirect(authorization_url)
                except:
                    # When running on localhost
                    creds = get_creds()
        else:
            try:
                flow = Flow.from_client_config(
                    json.loads(os.environ["CLIENT_CONFIG"]), SCOPES)
                flow.redirect_uri = (
                    "https://schedme.osc-fr1.scalingo.io/students/callback")
                authorization_url, state = flow.authorization_url(
                    access_type="offline")
                return redirect(authorization_url)
            except:
                # When running on localhost
                creds = get_creds()
    CalendarCredentials.objects.update_or_create(
        student=request.user, defaults={"credentials": pickle.dumps(creds)})
    # obtain google calendar data and store it in our database
    events = get_events(creds)
    for event in events:
        default_value = {
            "start": event["start"]["dateTime"],
            "end": event["end"]["dateTime"],
            "isLocal": False,
        }
        if "title" in event.keys():
            default_value["title"] = event["title"]
        Activity.objects.update_or_create(student=request.user,
                                          google_id=event["id"],
                                          defaults=default_value)
        messages.info(
            request,
            "The events in your calendar was successfully lodaded.",
        )
    return redirect("students:index")
Example #3
0
def request_oauth2_credentials():
    '''
    Steps:
		1. Set authorization parameters
		2. Redirect to Google's OAuth 2.0 server
		3. Google prompts the user for consent
		4. Handle the OAuth 2.0 server response
		5. Exchange authorization code for refresh and access tokens
	'''

    # Use the client_secret.json file to identify the application requesting
    # authorization. The client ID (from that file) and access scopes are required.
    flow = Flow.from_client_secrets_file(CLIENT_SECRETS_FILE,
                                         scopes=[YOUTUBE_UPLOAD_SCOPE])

    # Indicate where the API server will redirect the user after the user completes
    # the authorization flow. The redirect URI is required. The value 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 in your
    # Google API's account you will get a 'redirect_uri_mismatch' error.
    flow.redirect_uri = REDIRECT_URI

    # Generate URL for request to Google's OAuth 2.0 server.
    # Use kwargs to set optional request parameters.
    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',
    )

    # Your application redirects the user to Google along with the list of requested permissions.
    # The user decides whether to grant the permissions to your application.
    print(authorization_url)
    # To-DO: This step should be handled by a web server automatically and should not require user input when in production
    authorization_response = input(
        "Go to the above url, allow permissions and then when you get redirected to a new page, paste the url here"
    )

    # After the web server receives the authorization code, it can begin the exchange the authorization code for an access token.
    # First verify the authoriation server response by providing the same state token to protect against XSRF
    flow = Flow.from_client_secrets_file(CLIENT_SECRETS_FILE,
                                         scopes=[YOUTUBE_UPLOAD_SCOPE],
                                         state=state)
    flow.redirect_uri = REDIRECT_URI
    # Then exchange the authorization respnse (which contains the auth code) to get the credentials
    flow.fetch_token(authorization_response=authorization_response)
    credentials = flow.credentials

    return credentials
    def fetch_token(self,
                    code: str = None,
                    authorization_response: str = None,
                    state: str = None):
        """Complete the authentiction process.

        Parameters:
            code (``str``, *optional*):
                The code that the user got from google
                when they authorized your app. Defaults to None.

            authorization_response (``str``, *optional*):
                The reponse that the client sent
                to your server after the user authorized your app. Defaults to None.

            state (``str``, *optional*):
                The state used when you started the flow. Defaults to None.

        Returns:
            :obj:`~google_workspace.service.GoogleService`: Authenticated GoogleService.
        """

        self.flow = Flow.from_client_config(
            self.client_config,
            scopes=self.scopes,
            redirect_uri=self.redirect_uri,
            state=state,
        )
        self.flow.fetch_token(code=code,
                              authorization_response=authorization_response)
        self.credentials = self.flow.credentials
        self._retrieve_session_data()
        self._save_session()
        self._init_service()
        return self
Example #5
0
def callback(request):
    flow = Flow.from_client_config(json.loads(os.environ["CLIENT_CONFIG"]),
                                   SCOPES)
    flow.redirect_uri = "https://schedme.osc-fr1.scalingo.io/students/callback"
    authorization_response = request.build_absolute_uri()
    print("autho : ")
    print(authorization_response)
    flow.fetch_token(authorization_response=authorization_response)
    creds = flow.credentials
    CalendarCredentials.objects.update_or_create(
        student=request.user, defaults={"credentials": pickle.dumps(creds)})
    # obtain google calendar data and store it in our database
    events = get_events(creds)
    for event in events:
        default_value = {
            "start": event["start"]["dateTime"],
            "end": event["end"]["dateTime"],
            "isLocal": False,
        }
        if "title" in event.keys():
            default_value["title"] = event["title"]
        Activity.objects.update_or_create(student=request.user,
                                          google_id=event["id"],
                                          defaults=default_value)
        messages.info(
            request,
            "The events in your calendar was successfully lodaded.",
        )
    return redirect("students:index")
Example #6
0
    def get_authorize_url(self, scopes: list):
        flow = Flow.from_client_config(self.client_config,
                                       scopes=scopes,
                                       redirect_uri=self.redirect_uri)

        authorization_url, _ = flow.authorization_url(access_type="offline", include_granted_scopes="true")
        return authorization_url
Example #7
0
 def __init__(
     self,
     service_provider,
     redirect_uri,
     scopes=None,
 ):
     scopes = scopes or ['https://www.googleapis.com/auth/calendar.events']
     self.service_provider = service_provider
     self.credentials = service_provider.googlecredentials
     self.flow = Flow.from_client_config(
         {
             "web": {
                 "client_id":
                 self.credentials.client_id,
                 "project_id":
                 self.credentials.project_id,
                 "client_secret":
                 self.credentials.client_secret,
                 "auth_uri":
                 "https://accounts.google.com/o/oauth2/auth",
                 "token_uri":
                 "https://oauth2.googleapis.com/token",
                 "auth_provider_x509_cert_url":
                 "https://www.googleapis.com/oauth2/v1/certs",
             }
         },
         scopes,
     )
     self.flow.redirect_uri = redirect_uri
Example #8
0
def oauth_authorize():
    if "return_to" in request.args:
        session["redirect"] = request.args["return_to"]
    state = session.setdefault("analytics", {})

    credentials = None
    if "token" in state:
        credentials = pickle.loads(state["token"])

    if credentials and credentials.expired and credentials.refresh_token:
        credentials.refresh(Request())

    if credentials and credentials.valid:
        return redirect(session.get("redirect", "/"))

    authorization = {"web": session["google_cloud"]}
    print(json.dumps(authorization, indent=4))

    flow = Flow.from_client_config(authorization, scopes)
    host = os.getenv("API_URL", request.host_url[:-1])
    # flow.redirect_uri = "https://localhost:5000/oauth/callback/"
    flow.redirect_uri = "{}{}".format(host, url_for("oauth_callback"))

    auth_url, app.config["state"] = flow.authorization_url(
        prompt='consent', access_type='offline', include_granted_scopes='true')
    # For some reason redirect_uri is not attached by the lib
    return redirect(auth_url)
Example #9
0
def oauth_callback():
    state = request.args.get("state", None)
    if not state:
        return render_template("error.html",
                               errors=["No state provided to callback"])

    host = os.getenv("API_URL", request.host_url[:-1])
    try:
        authorization = {"web": session["google_cloud"]}

        flow = Flow.from_client_config(authorization, scopes, state=state)
        flow.redirect_uri = "{}{}".format(host, url_for("oauth_callback"))

        auth_url = request.url

        if auth_url.startswith("http://"):
            auth_url = "https" + auth_url[4:]

        flow.fetch_token(authorization_response=auth_url)

        sess_state = session["analytics"]
        sess_state.update({"token": pickle.dumps(flow.credentials)})
        session["analytics"] = sess_state

        with open(app.config["pickle"], "wb") as fin:
            pickle.dump(app.config["creds"], fin)
    except:
        tb.print_exc()
        return render_template(
            "error.html",
            error=[
                "An exception occured while attempting to complete the oauth flow"
            ])
    return redirect(session["redirect"])
Example #10
0
    def get():
        # Specify the state when creating the flow in the callback so that it can
        # verified in the authorization server response.
        result = MongoDB.instance().authorization.find_one({
            'service': 'calendar-service',
            'type': 'state'
        })
        state = result['state']

        flow = Flow.from_client_secrets_file('.secrets/credentials.json',
                                             SCOPES,
                                             state=state)
        flow.redirect_uri = request.args.get('redirect_uri')

        # Use the authorization server's response to fetch the OAuth 2.0 tokens.
        authorization_response = request.url
        flow.fetch_token(authorization_response=authorization_response)

        # Store credentials in mongo.
        credentials = flow.credentials
        MongoDB.instance().authorization.replace_one(
            {
                'service': 'calendar-service',
                'type': 'credentials'
            },
            credentials_to_dict(credentials),
            upsert=True,
        )

        return make_response({'message': 'Successfully authorized.'}, 200)
Example #11
0
    def get():
        flow = Flow.from_client_secrets_file('.secrets/credentials.json',
                                             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.args.get('redirect_uri')

        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.
        MongoDB.instance().authorization.replace_one(
            {
                'service': 'calendar-service',
                'type': 'state'
            },
            {
                'service': 'calendar-service',
                'type': 'state',
                'state': state
            },
            upsert=True,
        )

        return {'authorization_url': authorization_url}
Example #12
0
def oauth2callback():
  # Specify the state when creating the flow in the callback so that it can
  # verified in the authorization server response.
  state = session['state']

  flow = Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE,
      scopes=None,        state=state,
      redirect_uri=url_for('oauth2callback', _external=True)
  )



  # Use the authorization server's response to fetch the OAuth 2.0 tokens.
  authorization_response = 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
  session['credentials'] = credentials_to_dict(credentials)


  

  return redirect('/')
Example #13
0
def oauth2_request(req):
    # meat is here: https://developers.google.com/identity/protocols/oauth2/web-server#python

    if req.method == "POST":
        address = req.POST['address']
        flow = Flow.from_client_config(
            client_config={
                "web": {
                    "client_id": env("OAUTH_CLIENT_ID"),
                    "client_secret": env("OAUTH_CLIENT_SECRET"),
                    # "callbackUrl": "http://localhost:8000",
                    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
                    "token_uri": "https://accounts.google.com/o/oauth2/token"
                }
            },
            scopes=["https://www.googleapis.com/auth/fitness.activity.read"])

        flow.redirect_uri = "http://localhost:8000/oauth2callback/"

        auth_url, _ = flow.authorization_url(prompt='consent',
                                             access_type='offline',
                                             include_granted_scopes='true')
        resp = Response(status=302, location=auth_url)
        resp.set_cookie('ADDRESS', address)
        return resp

    return get_template('request.html').render()
Example #14
0
def complete_google_auth(request):
    """Admin view that handles the redirect from Google after completing Google auth"""
    if not settings.FEATURES.get("COUPON_SHEETS"):
        raise Http404
    state = request.session.get("state")
    if not state:
        raise GoogleAuthError(
            "Could not complete Google auth - 'state' was not found in the session"
        )
    flow = Flow.from_client_config(generate_google_client_config(),
                                   scopes=REQUIRED_GOOGLE_API_SCOPES,
                                   state=state)
    flow.redirect_uri = urljoin(settings.SITE_BASE_URL,
                                reverse("complete-google-auth"))
    flow.code_verifier = request.session["code_verifier"]
    flow.fetch_token(code=request.GET.get("code"))

    # Store credentials
    credentials = flow.credentials
    with transaction.atomic():
        google_api_auth, _ = GoogleApiAuth.objects.select_for_update(
        ).get_or_create()
        google_api_auth.requesting_user = request.user
        google_api_auth.access_token = credentials.token
        google_api_auth.refresh_token = credentials.refresh_token
        google_api_auth.save()

    return redirect("{}?success=auth".format(reverse("sheets-admin-view")))
Example #15
0
def authorize():
    '''
    Create a flow instance to manage the OAuth2 Authorization Grant Flow steps

    .. :quickref: User; Create a flow instance to manage the OAuth2
    '''
    # Check if user is logged_in, then redirect to main page.
    if session.get('logged_in', None):
        flash('You are already logged in.', 'warning')
        return redirect(url_for('main.list_categories'))

    # Create the flow instance using the client secret file
    flow = Flow.from_client_secrets_file(app.config['CLIENT_SECRET_FILE'],
                                         scopes=app.config['SCOPES'])
    # Add the redirect_uri to the oauth2session
    flow.redirect_uri = url_for('.oauth2callback', _external=True)

    # Generate the Authorization URL. Step 1 in the Oauth2.0 Authorization Flow
    authorization_url, state = flow.authorization_url(
        # Enable offline access to prevent re-prompting the user for permission
        access_type='offline',
        # Enable incremental authorization.
        include_granted_scopes='true')

    # Store the state in the session to verify the callback.
    session['state'] = state

    # Redirect the user to Google OAuth page to obtain consent
    return redirect(authorization_url)
Example #16
0
def get_flow(
    redirect_uri: str,
    path_to_secrets: str,
    verification_string: str,
    state=None,
) -> 'Flow':
    ''' 
    Utility method to handle OAuth conversation with Google

    Params:
    -------
        redirect_uri: str
            Path to callback endpoint
        path_to_secrets: str
            Path to json file containing oauth secrets
        verification_string: str
            Random string to serve as an auth check on the callback

    '''

    flow = Flow.from_client_secrets_file(
        path_to_secrets,
        scopes=os.environ.get('SCOPES').split(','),
        state=state,
    )

    flow.redirect_uri = redirect_uri
    flow.code_verifier = verification_string
    return flow
Example #17
0
def CredentialsFlowWrapper(client, credentials_only=False, **kwargs):

    # relax scope comparison, order and default scopes are not critical
    os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1'

    # parse credentials from file or json
    if RE_CREDENTIALS_JSON.match(client):
        client_json = json.loads(client)
    else:
        with open(client, 'r') as json_file:
            client_json = json.load(json_file)

    if credentials_only:
        return client_json
    else:
        if 'installed' in client_json:
            flow = InstalledAppFlow.from_client_config(client_json,
                                                       APPLICATION_SCOPES,
                                                       **kwargs)
        else:
            flow = Flow.from_client_config(client_json, APPLICATION_SCOPES,
                                           **kwargs)

        flow.user_agent = APPLICATION_NAME

        return flow
Example #18
0
def google_auth_callback():
    flow = Flow.from_client_config(
        json.loads(os.getenv('GOOGLE_CREDENTIALS')),
        scopes=['https://www.googleapis.com/auth/photoslibrary.readonly'],
    )

    flow.redirect_uri = url_for('api.google_auth_callback', _external=True)

    authorization_response = request.url
    flow.fetch_token(authorization_response=authorization_response)

    if 'error' in authorization_response:
        return make_response(
            jsonify({
                'status':
                401,
                'success':
                False,
                'message':
                f"authentication error: {authorization_response['error']}"
            }))

    app.google_credentials = flow.credentials

    return redirect(url_for('photo_gallery'))
Example #19
0
def ViewCourseWork(chat_id, course_id):

    course_id = ''
    creds = None
    pickleToken_path = "AddCourse/" + str(chat_id) + "_token.pickle"
    credentials_path = "AddCourse/credentials.json"

    if os.path.exists(pickleToken_path):
        with open(pickleToken_path, 'rb') as token:
            creds = pickle.load(token)

    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = Flow.from_client_secrets_file(credentials_path, SCOPES)
            creds = flow.run_local_server(port=users)

        with open(pickleToken_path, 'wb') as token:
            pickle.dump(creds, token)

    service = build('classroom', 'v1', credentials=creds)

    students_list = service.courses().courseWork().list(
        courseId=course_id).execute()
    return students_list
Example #20
0
 def build_flow(self, state=None):
     flow = Flow.from_client_config(
         self.config,
         scopes=self.scopes,
         redirect_uri=self.redirect_uri,
         state=state)
     return flow
Example #21
0
def auth():
    token = oauth.google.authorize_access_token()
    user = oauth.google.parse_id_token(token)
    session["user"] = user
    session["token"] = token

    sub = str(user["sub"])
    row = db.execute("SELECT * FROM users WHERE id = ?", sub)

    # Authorize the user
    flow = Flow.from_client_config(client_config=app.config["CLIENT_CONFIG"],
                                   scopes=SCOPES)

    flow.redirect_uri = url_for("oauth2callback", _external=True)

    authorization_url, state = flow.authorization_url(
        access_type="offline", login_hint=sub, include_granted_scopes="true")

    # Store state in session
    session["state"] = state

    # Ensure user is logging in for the first time
    if len(row) == 0:
        # Add user to database
        db.execute("INSERT INTO users (id) VALUES (?)", sub)

    return redirect(authorization_url)
Example #22
0
def oauth2callback():

    state = session["state"]

    flow = Flow.from_client_config(client_config=app.config["CLIENT_CONFIG"],
                                   scopes=SCOPES,
                                   state=state)
    flow.redirect_uri = url_for("oauth2callback")

    # Use the authorization server's response to fetch the OAuth 2.0 tokens.
    authorization_response = request.url
    flow.fetch_token(authorization_response=authorization_response)

    # Store credentials in the session.
    credentials = flow.credentials
    session["credentials"] = {
        "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
    }

    # Flash message
    flash("Hello, " + session["user"]["given_name"] + "!")

    return redirect("/")
Example #23
0
    def credentialsCheck(self):

        print('credentialsCheck::starting')

        if not self.creds or not self.creds.valid:
            if self.creds and self.creds.expired \
                and self.creds.refresh_token:
                self.creds.refresh(Request())
            else:
                '''
                pathChecks is done here, this will only run at first launch
                after checking, we set the defaults values programmatically.
                '''
                self.pathChecks([self.config, self.download_path])
                self.createConfigBody()

                flow = Flow.from_client_secrets_file(
                    self.client_id,
                    header.SCOPES,
                    redirect_uri='urn:ietf:wg:oauth:2.0:oob')
                self.flow = flow

                (auth_url, _) = flow.authorization_url(prompt='consent')

                pyotherside.send('authUrl', str(auth_url))
Example #24
0
def get_credentials():
    """Generates new credentials for google api.

    TODO: google_auth has yet to implement storage, so that may have wait for
    another day.
    TODO: This also doesn't automatically open in your browser.

    """
    # We only need read permissions.
    scopes = [
        'https://www.googleapis.com/auth/drive.readonly',
        'https://www.googleapis.com/auth/spreadsheets.readonly'
    ]

    flow = Flow.from_client_secrets_file(
        'client_secret.json', scopes, redirect_uri='urn:ietf:wg:oauth:2.0:oob')

    auth_url, _ = flow.authorization_url(prompt='consent')
    print('Go to')
    print(auth_url)
    print('and copy Auth Code')

    code = input('Enter auth code: ')
    print("Fetching Token.")
    flow.fetch_token(code=code)
    return flow.credentials
Example #25
0
def get_refresh_token():
    # as we don't use session from flask, then we save into user registry, at least for now
    if not app.auth.authorized([], 'global_preferences', 'POST'):
        return app.auth.authenticate()

    secrets = request.files.get('secretsFile', None)
    if secrets is None:
        return api_error('Please provide your youtube credentials', 400)

    secrets.seek(0)
    file_content = secrets.read()
    yt_data = json.loads(bytes2string(file_content))

    if 'web' not in yt_data:
        return api_error(
            'OAuth project has to be configured as web in google console', 400)

    # let's save secrets file content in db for future usage
    global_serv = get_resource_service('global_preferences')
    global_serv.save_preference(YT_KEY, yt_data)

    redirect_uri = flask.url_for('video_upload.oauth2callback',
                                 _external=True,
                                 _scheme=SCHEME)

    flow = Flow.from_client_config(yt_data,
                                   scopes=SCOPES,
                                   redirect_uri=redirect_uri)

    auth_url, _ = flow.authorization_url(prompt='consent',
                                         access_type='offline',
                                         include_granted_scopes='true')

    return make_response(auth_url, 200)
Example #26
0
def GetCourses(chat_id):

    creds = None
    pickleToken_path = "GetCourses/" + str(chat_id) + "_token.pickle"
    credentials_path = "GetCourses/credentials.json"

    if os.path.exists(pickleToken_path):
        with open(pickleToken_path, 'rb') as token:
            creds = pickle.load(token)

    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = Flow.from_client_secrets_file(credentials_path, SCOPES)
            creds = flow.run_local_server(port=users)

        with open(pickleToken_path, 'wb') as token:
            pickle.dump(creds, token)

    service = build('classroom', 'v1', credentials=creds)

    results = service.courses().list().execute()
    courses = results.get('courses', [])

    answer = []
    if not courses:
        answer.append('No courses found.')
    else:
        answer.append('Courses:')
        for course in courses:
            answer.append(course['name'])
    return answer
Example #27
0
def get_authorization_credentials(google_credentials, email=''):
    # Use the client_secret.json file to identify the application requesting
    # authorization. The client ID (from that file)
    # and access scopes are required.
    flow = Flow.from_client_config(
        google_credentials,
        scopes=['https://www.googleapis.com/auth/calendar'])

    # Indicate where the API server will redirect the user
    # after the user completes
    # the authorization flow. The redirect URI is required.
    flow.redirect_uri = 'http://proton-dev.com:5000/authorize'

    # Generate URL for request to Google's OAuth 2.0 server.
    # Use kwargs to set optional request parameters.
    return flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # res-prompting the user for permission. Recommended
        # for web server apps.
        access_type='offline',
        login_hint=email,
        prompt='consent',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true'
    )
Example #28
0
def finalize_google_auth():
	code = request.values.get('code')
	state = flask.session.get('state')
	code_verifier = flask.session.get('code_verifier')

	flask.session['state'], flask.session['code'], flask.session['code_verifier'] = None, None, None

	if (code is not None) & (code_verifier is not None):
		flow = Flow.from_client_config(CLIENT_JSON, scopes=SCOPES, state=state)
		flow.redirect_uri = flask.url_for('finalize_google_auth', _external=True, _scheme=HTTP_SCHEME)
		flow.fetch_token(code=code, code_verifier=code_verifier)

		credentials = flow.credentials
		current_google_calendar_user = current_user.google_calendar_user		
		primary_calendar = get_primary_calendar_details(credentials)
		if primary_calendar:
			if current_google_calendar_user:
				update_existing_user_creds(current_google_calendar_user, credentials, \
				                           primary_calendar, current_user)
			else:
				add_new_user_creds(credentials, primary_calendar, current_user)
		else:
			raise KeyError('Could not access a primary calendar for user %s' % current_user.id)
	else:
		return flask.jsonify({ 'errors': auth_form.errors })

	return flask.redirect('/#/settings')
Example #29
0
def _get_user_authentication_credentials(client_secret_file,
                                         scopes,
                                         credential_directory=None,
                                         local=False):
    """Returns user credentials."""
    if credential_directory is None:
        credential_directory = os.getcwd()
    elif credential_directory == 'global':
        home_dir = os.path.expanduser('~')
        credential_directory = os.path.join(home_dir, '.credentials')
        if not os.path.exists(credential_directory):
            os.makedirs(credential_directory)
    else:
        pass

    credentials_path = os.path.join(
        credential_directory,
        'sheets.googleapis.com-python.json')  # TODO Change hardcoded name?

    credentials = None
    if os.path.exists(credentials_path):
        # expect these to be valid. may expire at some point, but should be refreshed by google api client...
        credentials = Credentials.from_authorized_user_file(credentials_path,
                                                            scopes=scopes)

    if credentials:
        if credentials.expired and credentials.refresh_token:
            credentials.refresh(Request())
    else:
        if local:
            flow = InstalledAppFlow.from_client_secrets_file(
                client_secret_file, scopes)
            credentials = flow.run_local_server()
        else:
            flow = Flow.from_client_secrets_file(
                client_secret_file,
                scopes=scopes,
                redirect_uri='urn:ietf:wg:oauth:2.0:oob')
            auth_url, _ = flow.authorization_url(prompt='consent')

            print(
                'Please go to this URL and finish the authentication flow: {}'.
                format(auth_url))
            code = input('Enter the authorization code: ')
            flow.fetch_token(code=code)
            credentials = flow.credentials

    # Save the credentials for the next run
    credentials_as_dict = {
        'token': credentials.token,
        'refresh_token': credentials.refresh_token,
        'id_token': credentials.id_token,
        'token_uri': credentials.token_uri,
        'client_id': credentials.client_id,
        'client_secret': credentials.client_secret
    }
    with open(credentials_path, 'w') as file:
        file.write(json.dumps(credentials_as_dict))

    return credentials
Example #30
0
def authGoogle(client_secret_file, scopes, redirect_uri):
    """
    Function that signs into google

    Parameters
    client_secret_file : String name of the json file containing api access information
    scopes : List of strings indicating the scope of the API service
    redirect_uri : String url where to redirect after authentication flow

    Returns the url for google sign in prompt and the current state to be stored in Flask
    session for authGoogleComplete.

    """
    # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
    flow = Flow.from_client_secrets_file(client_secret_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 = redirect_uri

    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')

    return (authorization_url, state)
Example #31
0
def _get_user_authentication_credentials(client_secret_file, scopes, credential_directory=None):
    """Returns user credentials."""
    if credential_directory is None:
        credential_directory = os.getcwd()
    elif credential_directory == 'global':
        home_dir = os.path.expanduser('~')
        credential_directory = os.path.join(home_dir, '.credentials')
        if not os.path.exists(credential_directory):
            os.makedirs(credential_directory)
    else:
        pass

    credentials_path = os.path.join(credential_directory, 'sheets.googleapis.com-python.json')  # TODO Change hardcoded name?

    if os.path.exists(credentials_path):
        # expect these to be valid. may expire at some point, but should be refreshed by google api client...
        return Credentials.from_authorized_user_file(credentials_path, scopes=scopes)

    flow = Flow.from_client_secrets_file(client_secret_file, scopes=scopes,
                                         redirect_uri='urn:ietf:wg:oauth:2.0:oob')

    auth_url, _ = flow.authorization_url(prompt='consent')

    print('Please go to this URL and finish the authentication flow: {}'.format(auth_url))
    code = input('Enter the authorization code: ')
    flow.fetch_token(code=code)

    credentials = flow.credentials

    credentials_as_dict = {
        'token': credentials.token,
        'refresh_token': credentials.refresh_token,
        'id_token': credentials.id_token,
        'token_uri': credentials.token_uri,
        'client_id': credentials.client_id,
        'client_secret': credentials.client_secret
    }

    with open(credentials_path, 'w') as file:
        file.write(json.dumps(credentials_as_dict))

    return credentials