Exemple #1
0
 def exchange(self,
              client_secret,
              auth_code,
              web_client_id=dpy.IN,
              scopes=dpy.IN):
     return oauth2client.credentials_from_code(web_client_id, client_secret,
                                               scopes, auth_code)
Exemple #2
0
    def _enrichCredentialDictForAuth(self, credentialDICT, appObj):
        credentials = None
        try:
            ##credentials = self.getStaticData()['flow'].run_console()
            ##credentials = self.getStaticData()['flow'].step2_exchange(credentialDICT['code'])
            ##credentials = client.credentials_from_clientsecrets_and_code(
            ##  self.dataDict['ConfigJSON']['clientSecretJSONFile'],
            ##  ['profile', 'email'],
            ##  credentialDICT['code']
            ##)
            credentials = client.credentials_from_code(
                client_id=self.getStaticData()
                ['secretJSONDownloadedFromGoogle']["web"]["client_id"],
                client_secret=self.getStaticData()
                ['secretJSONDownloadedFromGoogle']["web"]["client_secret"],
                scope=['profile', 'email'],
                code=credentialDICT['code'])

        except Exception as err:
            print(err)  # for the repr
            print(str(err))  # for just the message
            print(err.args
                  )  # the arguments that the exception has been called with.
            raise services.src.constants.authFailedException

        #print("credentials:", credentials.to_json())
        #raise Exception('Call to google to get code')
        return {
            "code": credentialDICT["code"],
            "creds": json.loads(credentials.to_json())
        }
Exemple #3
0
def youtube_required_info(code):
    """
    Obtains youtube channel id and email from code.

    Args:
        code: Google user agent code.
    Returns:
        Id of youtube channel and google email.
    Raises:
        GoogleAccessError
        ChannelNotFoundError
    """
    try:
        creds = credentials_from_code(CLIENT_ID, CLIENT_SECRET, SCOPES, code)
    except FlowExchangeError as exchange_error:
        raise GoogleAccessError(exchange_error)
    # then can use cache
    service = build(OAUTH_API, OAUTH_VERSION, credentials=creds)
    google_account = service.userinfo()
    service = build(YOUTUBE_API, YOUTUBE_VERSION, credentials=creds)
    channels = service.channels()
    try:
        email = google_account.get(fields='email').execute()['email']
        channel = channels.list(part='id', mine=True, fields='items/id')
        channel_id = channel.execute()['items'][0]['id']
    except (KeyError, IndexError, HttpAccessTokenRefreshError, HttpError,
            AccessTokenCredentialsError,) as api_error:
        raise GoogleAccessError(api_error)
    if not ChannelInfo(channel_id).is_exists():
        raise ChannelNotFoundError()
    return channel_id, email
Exemple #4
0
 def google_oauth2_callback(self, d):
     '''
     Handle server-side oauth2 callback
     '''
     error = self.request.get('error')
     code = self.request.get('code')
     scope = self.request.get('scope')
     # state_scopes = self.request.get('state')
     if code:
         from settings.secrets import GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET
         from constants import SECURE_BASE
         base = 'http://localhost:8080' if tools.on_dev_server() else SECURE_BASE
         credentials = client.credentials_from_code(
             GOOGLE_CLIENT_ID,
             GOOGLE_CLIENT_SECRET,
             scope,
             code,
             redirect_uri=base + "/api/auth/google/oauth2callback")
         if self.user:
             cr_json = credentials.to_json()
             logging.debug(type(cr_json))
             self.user.set_integration_prop('google_credentials', cr_json)
             self.user.put()
             self.update_session_user(self.user)
     elif error:
         logging.error(error)
     self.redirect("/app/integrations")
Exemple #5
0
    def oauth_complete(self, request: Request):
        if (request.get_data()):
            app.logger.info(f'data:\n{request.get_data()}')
            auth_code = str(request.get_data(), encoding='utf-8')

        else:
            app.logger.error('No code sent!')
            return 'AUTH FAIL: No authentication code received.'

        project_credentials = json.loads(OAuth.fetch_file(
            self.bucket, 'client_secrets.json'),
                                         encoding='utf-8')

        credentials = client.credentials_from_code(
            client_id=project_credentials['web']['client_id'],
            client_secret=project_credentials['web']['client_secret'],
            scope=self.SCOPES,
            code=auth_code)

        email = credentials.id_token['email']

        token_details = {
            'access_token': credentials.access_token,
            'refresh_token': credentials.refresh_token
        }

        OAuth.write_file(self.bucket, f'{email}_user_token.json',
                         json.dumps(token_details).encode('utf-8'))

        return 'Authenticated!'
Exemple #6
0
 def auth_google(request, google_code):
     """ Authenticate with Google and return the user.
         https://developers.google.com/identity/sign-in/web/server-side-flow
         https://developers.google.com/gmail/api/auth/web-server
     """
     creds = client.credentials_from_code(settings.GOOGLE_CLIENTID,
                                          settings.GOOGLE_SECRET,
                                          settings.GOOGLE_SCOPES,
                                          google_code)
     creds.authorize(httplib2.Http())
     google_email = creds.id_token['email']
     # Check user is currently logged in
     if request.user and request.user.is_active:
         request.user.google_email = creds.id_token['email']
         request.user.google_creds = creds.to_json()
         request.user.save()
         log.info('Connected Google account %s to userid %s', google_email,
                  request.user)
         return request.user
     # User is not currently logged in
     user = User.objects.get(google_email=google_email)
     if user and user.is_active:
         request.user.google_creds = creds.to_json()
         login(request, user)
         log.info('Logged in via Google as %s', google_email)
         return user
Exemple #7
0
def authenticate():
  response_data = dict()
  code = request.data.decode('utf-8')

  csrf=request.args.get('_csrf_token', None) or abort(404)
  if csrf != session['_csrf_token']:
    return Response('Invalid state Parameter', status=401, content_type='application/json')

  if 'error' in request.args:
    return Response(json.dumps(dict(error=request.args['error'])),
          status=400,
          content_type='application/json')

  h = httplib2.Http()
  credentials = client.credentials_from_code(g.config['CLIENT_ID'],
        g.config['CLIENT_SECRET'],
        g.config['AUTH_SCOPE'],
        code,
        http=h)
  #pprint(credentials.refresh_token)
  h = credentials.authorize(http=h)

  service = discovery.build('plus', 'v1', http=h)
  person = None
  try:
    person = service.people().get(userId='me').execute()
  except client.AccessTokenRefreshError:
    return make_response('The credentials have been revoked or expired.',400)

  #pprint(person)
  try:
    user = User.objects.get(id=person['id'])
    # TODO: update if changed
    #pprint(user)
  except User.DoesNotExist:
    user = User(id=person['id'],
          given_name=person['name']['givenName'],
          family_name=person['name']['familyName'],
          display_name=person['displayName'],
          flags=dict(firstLogin=True))
    for email in person['emails']:
      if email['type'] == 'account':
        user.email = email['value']

  refresh_token = getattr(credentials, 'refresh_token', None)
  if refresh_token != None:
    user.refresh_token = refresh_token

  user.save()

  if user:
    #pprint(user.dict())
    login_user(user, redirect=False)

  # TODO: check for errors or something, respond with 400

  response = make_response(json.dumps(dict(user=user.dict()), 200))
  response.headers['Content-Type'] = 'application/json'
  return response
Exemple #8
0
def authcallback():
    code = request.args.get('code', None)
    if code:
        temp = credentials_from_code(CONFIG["client_id"], CONFIG["client_secret"], OAUTH_SCOPE, code, request.url_root + "authcallback")
        session["creds"] = temp.to_json()
        return redirect("/")
    else:
        return render_template("error.html", message=request.args.get("error", ""))
 def test_exchange_code_for_token(self):
     token = "asdfghjkl"
     payload = json.dumps({"access_token": token, "expires_in": 3600})
     http = HttpMockSequence([({"status": "200"}, payload.encode("utf-8"))])
     credentials = credentials_from_code(
         self.client_id, self.client_secret, self.scope, self.code, redirect_uri=self.redirect_uri, http=http
     )
     self.assertEqual(credentials.access_token, token)
     self.assertNotEqual(None, credentials.token_expiry)
Exemple #10
0
def google_complete_login(request, app, token):
    provider = GoogleProvider.get_instance()
    credentials = client.credentials_from_code(app.client_id, app.secret_key,
                                               provider.get_default_scope(),
                                               token.token)
    token.expires_at = credentials.token_expiry
    if credentials.refresh_token:
        token.token_secret = credentials.refresh_token
    return provider.social_login_from_response(request, credentials.id_token)
    def test_exchange_code_for_token_fail(self):
        http = HttpMockSequence([({"status": "400"}, b'{"error":"invalid_request"}')])

        try:
            credentials = credentials_from_code(
                self.client_id, self.client_secret, self.scope, self.code, redirect_uri=self.redirect_uri, http=http
            )
            self.fail("should raise exception if exchange doesn't get 200")
        except FlowExchangeError:
            pass
Exemple #12
0
def complete_login(team_id, code):
    creds = client.credentials_from_code(
        client_id=os.environ["GOOGLE_CLIENT_ID"],
        client_secret=os.environ["GOOGLE_CLIENT_SECRET"],
        scope=SCOPES,
        code=code,
    )

    # Save the credentials for the next run
    pickled = pickle.dumps(creds)
    redis_client.save(team_id, "google_token", pickled)
 def test_exchange_code_for_token(self):
   http = HttpMockSequence([
     ({'status': '200'},
     """{ "access_token":"asdfghjkl",
      "expires_in":3600 }"""),
   ])
   credentials = credentials_from_code(self.client_id, self.client_secret,
                                   self.scope, self.code, self.redirect_uri,
                                   http)
   self.assertEquals(credentials.access_token, 'asdfghjkl')
   self.assertNotEqual(None, credentials.token_expiry)
 def test_exchange_code_for_token(self):
   token = 'asdfghjkl'
   payload =simplejson.dumps({'access_token': token, 'expires_in': 3600})
   http = HttpMockSequence([
     ({'status': '200'}, payload),
   ])
   credentials = credentials_from_code(self.client_id, self.client_secret,
       self.scope, self.code, redirect_uri=self.redirect_uri,
       http=http)
   self.assertEquals(credentials.access_token, token)
   self.assertNotEqual(None, credentials.token_expiry)
 def test_exchange_code_for_token(self):
   token = 'asdfghjkl'
   payload = json.dumps({'access_token': token, 'expires_in': 3600})
   http = HttpMockSequence([
     ({'status': '200'}, payload.encode('utf-8')),
   ])
   credentials = credentials_from_code(self.client_id, self.client_secret,
       self.scope, self.code, redirect_uri=self.redirect_uri,
       http=http)
   self.assertEqual(credentials.access_token, token)
   self.assertNotEqual(None, credentials.token_expiry)
  def test_exchange_code_for_token_fail(self):
    http = HttpMockSequence([
      ({'status': '400'}, b'{"error":"invalid_request"}'),
      ])

    try:
      credentials = credentials_from_code(self.client_id, self.client_secret,
          self.scope, self.code, redirect_uri=self.redirect_uri,
          http=http)
      self.fail('should raise exception if exchange doesn\'t get 200')
    except FlowExchangeError:
      pass
Exemple #17
0
def auth_with_google(request):
    code = request.GET.get('code', '')
    if code is not '':
        credentials = client.credentials_from_code(
            SsoConfig.google_client_id,
            SsoConfig.google_client_secret,
            'profile',
            code,
            redirect_uri='http://localhost:8000/callback/google')
        return JsonResponse(credentials.id_token)
    else:
        return JsonResponse({'error': 'Error'})
Exemple #18
0
def auth_with_google(request):
    code = request.GET.get('code', '')
    if code is not '':
        credentials = client.credentials_from_code(
            SsoConfig.google_client_id,
            SsoConfig.google_client_secret,
            'profile',
            code,
            redirect_uri='http://localhost:8000/callback/google'
        )
        return JsonResponse(credentials.id_token)
    else:
        return JsonResponse({'error': 'Error'})
Exemple #19
0
def google_login():
    """Log in using google oauth2."""
    # protect against CSFR
    if request.args.get('state') != session['state']:
        response = make_response(json.dumps('Invalid state parameter.'), 401)
        response.headers['Content-Type'] = 'application/json'
        return response

    one_time_code = request.values["code"]
    credentials = None
    try:
        # upgrade one-time code from client into oauth2 credentials
        secrets =\
            json.loads(resource_string(__name__,
                                       "client_secrets.json").decode("utf-8"))
        credentials =\
            client.credentials_from_code(WEBAPP_CLIENT_ID,
                                         secrets["web"]["client_secret"],
                                         "",
                                         one_time_code)
    except client.FlowExchangeError:
        response =\
            make_response(json.dumps('Failed to upgrade google auth code.'),
                          401)
        response.headers['Content-Type'] = 'application/json'
        return response

    username = credentials.id_token["sub"]
    user = _USER_REPO.get_by_username(username, AuthProvider.google)
    response =\
        make_response(json.dumps(
            'Internal error - please report to application author.'), 500)
    response.headers['Content-Type'] = 'application/json'
    if user and user.active:
        # active user logged in
        print("User logged in.")
        session["user_email"] = credentials.id_token["email"]
        session["user_active"] = user.active
        session["user_admin"] = user.admin
        return "", 200
    elif user and not user.active:
        print("Deactivated user.")
        response =\
            make_response(json.dumps('Deactivated user.'), 403)
        response.headers['Content-Type'] = 'application/json'
    else:
        print("Unknown user.")
        response =\
            make_response(json.dumps('Unknown user.'), 403)
        response.headers['Content-Type'] = 'application/json'
    return response
Exemple #20
0
    def post(self):
        data = json.loads(self.request.body)
        settings = model.show_settings()
        config = json.loads(settings.config)
        config_web = config.get('web', {})
        client_id = config_web.get('client_id', '')
        client_secret = config_web.get('client_secret', '')

        credentials = client.credentials_from_code(
            client_id, client_secret,
            ['https://www.googleapis.com/auth/dfatrafficking'], data['code'])
        project = model.create_project(data['name'], data['profileId'],
                                       credentials.to_json())
        self.as_json(as_dict(project))
 def test_exchange_code_for_token(self):
     http = HttpMockSequence([
         ({
             'status': '200'
         }, """{ "access_token":"asdfghjkl",
    "expires_in":3600 }"""),
     ])
     credentials = credentials_from_code(self.client_id,
                                         self.client_secret,
                                         self.scope,
                                         self.code,
                                         redirect_uri=self.redirect_uri,
                                         http=http)
     self.assertEquals(credentials.access_token, 'asdfghjkl')
     self.assertNotEqual(None, credentials.token_expiry)
Exemple #22
0
    def create(self, request):
        serializer = GoogleAuthSerializer(data=request.data)

        if not serializer.is_valid():
            raise ParseError(detail=serializer.errors)

        credentials = client.credentials_from_code(self.CLIENT_ID, self.CLIENT_SECRET,
                                                   scope=['https://www.googleapis.com/auth/gmail.labels',
                                                          'https://www.googleapis.com/auth/gmail.readonly',
                                                          'https://www.googleapis.com/auth/gmail.modify'],
                                                   code=serializer.validated_data['code'],
                                                   redirect_uri=serializer.validated_data['redirect_uri'])

        service = build('gmail', 'v1', credentials=credentials)
        print(service.users().labels().list(userId='me').execute())
        return Response("a mers")
Exemple #23
0
def gconnect():
    # If this request does not have `X-Requested-With` header or the
    # anti-forgery state token is not the expected one this could be a CSRF
    if not request.is_xhr or request.args.get('state') != session['state']:
        response = make_response(json.dumps('Invalid request.'), 401)
        response.headers['Content-Type'] = 'application/json'
        return response

    authCode = request.data

    try:
        # Exchange auth code for access token, refresh token, and ID token
        appInfo = json.loads(app.config['GOOGLE_CLIENT_SECRET'])
        credentials = credentials_from_code(
            client_id=appInfo['web']['client_id'],
            client_secret=appInfo['web']['client_secret'],
            auth_uri=appInfo['web']['auth_uri'],
            token_uri=appInfo['web']['token_uri'],
            scope=['profile', 'email'],
            code=authCode)

    except FlowExchangeError as e:
        response = make_response(
            json.dumps('Failed to upgrade the authorization code.'), 401)
        response.headers['Content-Type'] = 'application/json'
        return response

    del session['state']
    session['credentials'] = credentials.to_json()

    # Call Google+ API to get user's profile info
    httpAuth = credentials.authorize(httplib2.Http())
    gplusService = build('plus', 'v1', http=httpAuth)
    userInfo = gplusService.people().get(userId='me').execute()

    user = createOrSignInUser(email=credentials.id_token["email"],
                              name=userInfo["name"]["givenName"],
                              lastName=userInfo["name"]["familyName"],
                              picture=userInfo["image"]["url"])

    resp = {
        'status': 'success',
        'userName': "******".format(user.name, user.last_name),
        'userPicture': user.picture
    }

    return jsonify(resp)
Exemple #24
0
    def post(self):
        """
        Get a google token pair
        """
        args = google_tokens_parser.parse_args()
        client_id = current_app.config.get('GOOGLE_CLIENT_ID')
        client_secret = current_app.config.get('GOOGLE_CLIENT_SECRET')
        auth_code = args.auth
        try:
            credentials = client.credentials_from_code(client_id,
                                                       client_secret,
                                                       scope='',
                                                       code=auth_code)
        except client.FlowExchangeError as e:
            api.abort(400, e)

        r = requests.get('{}?access_token={}'.format(fetch_info_url,
                                                     credentials.access_token))
        content = json.loads(r.content.decode('utf-8'))
        user = User.from_db_by_email(content['email'])
        if not user:
            try:
                user = User.create_google(content['email'])
            except ValueError as e:
                api.abort(
                    400,
                    'Cannot create the user. More information: {}'.format(e))
        TokenModel.create_pair(user,
                               raw_access={
                                   'type': 'access-google',
                                   'value': credentials.access_token,
                                   'expiration_date': credentials.token_expiry
                               },
                               raw_refresh={
                                   'type': 'refresh-google',
                                   'value': credentials.refresh_token
                               })
        db.session.commit()
        return {
            'name': user.name,
            'access_token': credentials.access_token,
            'rights': user.rights
        }, 200
Exemple #25
0
def google_register():
    """Register a user using a google provider."""
    # protect against CSFR
    if request.args.get('state') != session['state']:
        response = make_response(json.dumps('Invalid state parameter.'), 401)
        response.headers['Content-Type'] = 'application/json'
        return response

    one_time_code = request.values["code"]
    credentials = None
    try:
        # upgrade one-time code from client into oauth2 credentials
        secrets =\
            json.loads(resource_string(__name__,
                                       "client_secrets.json").decode("utf-8"))
        credentials =\
            client.credentials_from_code(WEBAPP_CLIENT_ID,
                                         secrets["web"]["client_secret"],
                                         "",
                                         one_time_code)
    except client.FlowExchangeError:
        response =\
            make_response(json.dumps('Failed to upgrade google auth code.'),
                          401)
        response.headers['Content-Type'] = 'application/json'
        return response

    username = credentials.id_token["sub"]
    if not _USER_REPO.exists_by_username(username, AuthProvider.google):
        # add user
        user = User(username=username,
                    provider=AuthProvider.google,
                    email=credentials.id_token["email"])
        _USER_REPO.add_user(user)
        print("Added user")
        return "", 200

    print("User already registered.")
    response =\
        make_response(json.dumps('User already registered.'), 409)
    response.headers['Content-Type'] = 'application/json'
    return response
def handshake_oauth(code):
    # 일회성 코드와 Access 토큰, Refresh 토큰 교환
    credentials = client.credentials_from_code(GOOGLE_CLIENT_ID,
                                               GOOGLE_CLIENT_SECRET,
                                               ['profile', 'email'], code)

    # 이메일과 아이디 받기
    access_token = credentials.access_token
    refresh_token = credentials.refresh_token
    email = credentials.id_token['email']
    name = credentials.id_token['name']
    expiresAt = datetime.now() + timedelta(hours=1)

    # 반환
    return {
        'accessToken': access_token,
        'refreshToken': refresh_token,
        'email': email,
        'name': name,
        # 1시간 후 로그아웃
        'expiresAt': expiresAt.timestamp()
    }
Exemple #27
0
def get_credentials(code, origin):
    """ Creates a google oauth2 client credentials instance, validating
    the provided token with google.

    Arguments
    ---------
    code : str
        The oAuth2 code from the webflow

    Raises
    ------
    GoogleOAuth2Exception
        When an errors occures during token validation

    Returns
    -------
    oauth2client.client.OAuth2Credentials
        Google oAuth2 client credentials instance
    """

    redirect_uri = ''
    for redirect in config.GOOGLE_REDIRECT_URI.split(","):
        current_app.logger.info('[Google auth] redirect {}'.format(redirect))
        o = furl(origin)
        r = furl(redirect)
        if o.host == r.host:
            redirect_uri = redirect

    try:
        credentials = credentials_from_code(config.GOOGLE_CLIENT_ID,
                                            config.GOOGLE_CLIENT_SECRET,
                                            '',
                                            code,
                                            redirect_uri=redirect_uri)
    except FlowExchangeError as e:
        raise GoogleOAuth2Exception(
            'Problem authenticating with Google: {0}'.format(e.message))

    return credentials
  def create_user(self, code, id_token):
    self.logger.debug('creating user')
    cs = Util.get_client_secrets()
    credential = credentials_from_code(cs['client_id'], cs['client_secret'],
      'https://www.googleapis.com/auth/plus.me', code)
    google_user_info = self.get_google_user_info(credential)
    self.logger.debug('name: %s' % (google_user_info['name']))
    (user, created) = User.objects.get_or_create(username=str(id_token['sub']),
      first_name=google_user_info['name']['givenName'],
      last_name=google_user_info['name']['familyName'])

    storage = Storage(Solver_User_Info, 'user', user, 'credential')
    self.logger.debug('created storage')
    try:
      storage.put(credential)
      self.logger.debug('stored credential')
    except Exception as e:
      print(e)
    self.logger.debug('stored credntial')
    user.solver_user_info.google_id = id_token['sub']
    user.solver_user_info.save()
    self.logger.debug('added google id')
    return user
Exemple #29
0
  def oauth_complete(self, request: Request):
    if(request.get_data()):
      app.logger.info(f'data:\n{request.get_data()}')
      auth_code = str(request.get_data(), encoding='utf-8')

    else:
      app.logger.error('No code sent!')
      return 'AUTH FAIL: No authentication code received.'

    project_credentials = Credentials(project=self.project,
                                      email=None).project_credentials

    credentials = client.credentials_from_code(
        client_id=project_credentials.client_id,
        client_secret=project_credentials.client_secret,
        scope=self.SCOPES,
        code=auth_code
    )

    email = credentials.id_token['email']
    cm = Credentials(project=self.project, email=email)
    cm.store_credentials(creds=credentials)

    return 'Authenticated!'
Exemple #30
0
 def get_credentials(self, args):
     credentials = client.credentials_from_code(CLIENT_ID, CLIENT_SECRET, scope='', code=args['auth_code'])
     print(credentials)
Exemple #31
0
# python example for the exchange of auth code to refresh token
# Reference: https://oauth2client.readthedocs.io/en/latest/source/oauth2client.client.html#

from oauth2client import client

CLIENT_ID = 'YOUR_CLIENT_ID'

CLIENT_SECRET = 'YOUR_CLIENT_SECRET'


if __name__ == "__main__":
    auth_code = 'auth_code_from_client'

    try:
        credentials = client.credentials_from_code(CLIENT_ID, CLIENT_SECRET, scope='', code=auth_code)
    except client.FlowExchangeError as e:
        print(e)
    else:
        print('refresh_token:', credentials.refresh_token)
        print('access_token:', credentials.access_token)
        print('token_expiry:', credentials.token_expiry)
Exemple #32
0
    def auth_user(self, request):
        """
        Verifies the identity of the user via Oauth using the user's auth code. If the
        user already exists, we return a JWT with their claim. If they don't already exist, we create their
        user in the datastore and return a JWT with their claim.
        """
        # we are using this application to make the request on behalf of the user
        client_id = os.environ.get('CLIENT_ID')
        client_secret = os.environ.get('CLIENT_SECRET')
        # code associated with the user so we can verify their identity
        auth_code = request.auth_code

        if client_secret is None:
            raise endpoints.InternalServerErrorException(
                'This application has not been configured with proper credentials'
            )

        # make sure we actually have the keys
        if auth_code.replace(' ', '') == '':
            raise endpoints.BadRequestException('Auth code not provided')

        # verifying the user
        try:
            # we have the credentials associated with this client so
            # let's go ahead and verify the user using OAuth
            credentials = client.credentials_from_code(client_id,
                                                       client_secret, 'email',
                                                       auth_code)
            http_auth = credentials.authorize(httplib2.Http())
            service = discovery.build('oauth2', 'v2', http=http_auth)
            userinfo = service.userinfo().get().execute(
            )  # we should have the userinfo
        except:
            # were we given the wrong access token?
            raise endpoints.BadRequestException(
                'Unable to authenticate access token. Verify the client ID is correct'
            )

        # ok now create the user and jwt and pass it back!
        email = userinfo.get('email')

        if email is None:
            raise endpoints.BadRequestException(
                'Unable to fetch email for this user')

        # check whether the user exists
        user = User.get_by_id(email)

        if user is None:
            try:
                # create the user
                username = email.split('@')[0]
                user = User(username=username, email=email)
                user.key = Key('User', email)
                user.put()
            except Exception as e:
                # print e.message
                raise endpoints.InternalServerErrorException(
                    'An error occurred while attempting to create user')

        # create the JWT and send it back to the user. This should
        # be used on all subsequent requests!
        payload = {"user_key": user.key.urlsafe()}

        try:
            jwt = token.encode_jwt(payload)
        except LookupError:
            raise endpoints.InternalServerErrorException(
                'An error occurred while attempting to create credentials')

        return UserAuthFormResponse(jwt_token=jwt)
# Python example for the exchange of auth code to refresh token
# https://pypi.org/project/oauth2client/
# Reference: https://oauth2client.readthedocs.io/en/latest/source/oauth2client.client.html#

from oauth2client import client

CLIENT_ID = 'YOUR_CLIENT_ID'
CLIENT_SECRET = 'YOUR_CLIENT_SECRET'

if __name__ == "__main__":
    auth_code = 'auth_code_from_client'

    try:
        credentials = client.credentials_from_code(
            CLIENT_ID,
            CLIENT_SECRET,
            scope='https://www.googleapis.com/auth/drive',
            code=auth_code)
    except client.FlowExchangeError as e:
        print(e)
    else:
        print('refresh_token:', credentials.refresh_token)
        print('access_token:', credentials.access_token)
        print('token_expiry:', credentials.token_expiry)