Adding member to a Google group using Google API - google-api

I'm trying to add email ids to a Google group using google APIs and Python3. I need help, figuring out what scopes it needs since I am getting the error:
Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential.
My code:
from __future__ import print_function
import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/admin.directory.user']
def main():
"""Shows basic usage of the Admin SDK Directory API.
Prints the emails and names of the first 10 users in the domain.
"""
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
print(creds)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'client_secrets.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.json', 'w') as token:
token.write(creds.to_json())
service = build('admin', 'directory_v1', credentials=creds)
group_result = service.groups().insert(body={
'groupKey': 'with-automated-addition-of-members#googlegroups.com', # group key
'email': 'sumukhrajubhat2701#gmail.com' # user email who need to insert in google groups
}).execute()
print(group_result)
Anyone please help me with the issue.

You can always check the docs for each method to see what scope it requires. In your case
groups.insert requires one of the following scopes.

Related

errors when trying to tweet using tweepy

I am working on an academic research project and I am trying to send out tweets using the the Twitter API. The error I am receiving repeatedly is
Forbidden: 403 Forbidden
Your client app is not configured with the appropriate oauth1 app permissions for this endpoint.
import tweepy
#from tweepy import OAuthHandler
ACCESS_KEY = 'xxx'
ACCESS_SECRET = 'xxx'
CONSUMER_KEY = 'xxx'
CONSUMER_SECRET = 'xxx'
api = tweepy.Client(bearer_token='xxx',
access_token=ACCESS_KEY,
access_token_secret=ACCESS_SECRET,
consumer_key=CONSUMER_KEY,
consumer_secret=CONSUMER_SECRET)
api.create_tweet(text='I want to Tweet')
Here is my code. The authentication raises no errors. Just the attempt at tweeting.
You can fix the problem by activating Read / Write in the Oauth section of your application, and then you shall regenerate the "Access Token and Secret".
You can check that are properly recreated when you see:
Created with Read and Write permissions
EDIT as of 10/February/2023: You are now required to ask for Elevated access if you want to have read + write permission. You only have read access from the V2 API Endpoints as of today

Can I limit the available scopes on a Google API service account?

I have done the following:
Created a project in Google API console
Enabled the Google Drive API in the project
Created a service account
Shared a Google Drive folder with the service account
Connected successfully to Google Drive and retrieved the list of folders and files shared with the service account.
When you create an OAuth client ID, you can limit that to predefined scopes. As far as I can tell, the service account has access to any Google Drive scope. I wanted to tighten that down to the following scope: https://www.googleapis.com/auth/drive.readonly just as a reassurance that there's no way the Google Drive app I'm making unintentionally adds/edits/deletes any files.
I know I can add the account to different roles. However, I looked through the list multiple times and none of them are related to Google Drive. I attempted to make my own role, but the available permissions on that screen do not reference Google Drive either. It's possible I missed something or there's another place I could look. Any suggestions?
To limit the scope a Service Account, you have to specify the scope on the server-side.
Service accounts are special Google accounts that can be used by
applications to access Google APIs programmatically via OAuth 2.0. A
service account uses an OAuth 2.0 flow that does not require human
authorization. Instead, it uses a key file that only your application
can access.
For example:
In python, you can specify the scope of a service account by creating a list of scopes and use it as parameter when getting the credentials.
Folder and Files:
python:
Search all image with jpeg extension:
import httplib2
import os
from apiclient import discovery
from google.oauth2 import service_account
scopes = ["https://www.googleapis.com/auth/drive.readonly"]
secret_file = os.path.join(os.getcwd(), 'client_secret.json')
credentials = service_account.Credentials.from_service_account_file(secret_file, scopes=scopes)
service = discovery.build('drive', 'v3', credentials=credentials)
page_token = None
while True:
response = service.files().list(q="mimeType='image/jpeg'",
spaces='drive',
fields='nextPageToken, files(id, name)',
pageToken=page_token).execute()
for file in response.get('files', []):
# Process change
print('Found file: %s' % (file.get('name')))
page_token = response.get('nextPageToken', None)
if page_token is None:
break
Output:
Found file: cute-puppy.jpg
Creating folder with readonly scope:
import httplib2
import os
from apiclient import discovery
from google.oauth2 import service_account
scopes = ["https://www.googleapis.com/auth/drive.readonly"]
secret_file = os.path.join(os.getcwd(), 'client_secret.json')
credentials = service_account.Credentials.from_service_account_file(secret_file, scopes=scopes)
service = discovery.build('drive', 'v3', credentials=credentials)
file_metadata = {
'name': 'Invoices',
'mimeType': 'application/vnd.google-apps.folder'
}
file = service.files().create(body=file_metadata,
fields='id').execute()
Error message:
<HttpError 403 when requesting https://www.googleapis.com/drive/v3/files?fields=id&alt=json returned "Insufficient Permission: Request had insufficient authentication scopes.". Details: "Insufficient Permission: Request had insufficient authentication scopes.">
References:
Google Auth Python
OAuth Scopes

python-keycloak package with KeycloakOpenID : logout does not work

I have a keycloak docker container (pulled image jboss/keycloak ) and a Django 2.2 web container. For integration of django with keycloak social-auth-app-django was used. Login works fine. Now trying to implement logout using python-keycloak following instructions described here:
https://github.com/marcospereirampj/python-keycloak :
from keycloak import KeycloakOpenID
keycloak_openid = KeycloakOpenID(server_url="http://<my IP>:8080/auth/",
client_id="<client_id>",
realm_name="<my realm name>",
client_secret_key="<my secret>",
verify=True)
config_well_know = keycloak_openid.well_know()
token = keycloak_openid.token("<username>", "<password>")
print(token) # all tokens returned ok
userinfo = keycloak_openid.userinfo(token['access_token'])
print ("userinfo:", userinfo) # userinfo returned ok
keycloak_openid.logout(token['refresh_token'])
in the container log:
Some clients have been not been logged out for user <username> in <my realm name> realm: <client_id>
No logout happens, still can browse the site.
What's missing? Thanks
UPDATE
Maybe I understood the problem. The token I get from keycloak_openid.token() call is not the token that was generated for me at the moment of login. The only token that can be fed to keycloak_openid.logout() call for it to work is that original token ('refresh_token' key value of the token dict, to be specific). Calling keycloak_openid.refresh_token() also issues a new token which is rejected as logout credential. But the originally issued refresh_token does not seem to be stored anywhere - sessions, cookies or keycloak db. (Note: I did find access_token, it's in the django DB in social_auth_usersocialauth table, but I need refresh_token). However, it's dumped to the console output at the moment of login, so if I copy it and call keycloak_openid.logout() with it, it does logout from keycoak. The question is where can I find that original refresh_token?
I used to experience the same issue. What helped was
Going to admin page and location your user in the realm
open your browser's developer console and monitor the networks
Go to sessions tab on keycloak and click log out
Observe which end point is being called and mimic that in your python backend, with proper header in the request.
Hope this helps!
I understand that this question is outdated, but I managed to logout by this:
Add the following variables to settings.py:
SOCIAL_AUTH_KEYCLOAK_LOGOUT_URL = 'https://your-keycloak/auth/realms/your-realm/openid-connect/logout'
SOCIAL_AUTH_KEYCLOAK_EXTRA_DATA=[("refresh_token","refresh_token")]
Now it will save the refresh token in extra_data.
Add into urlpatterns list in urls.py:
url(r'^logout/$', views.logout, name='logout'),
Add the logout view with communication code to views.py:
from django.contrib.auth import logout as auth_logout
import requests
def logout(request):
if request.user.is_authenticated:
user = request.user
if user.social_auth.filter(provider='keycloak'):
social = user.social_auth.get(provider='keycloak')
access_token=social.extra_data['access_token']
refresh_token=social.extra_data['refresh_token']
#logger.debug(access_token) # you can view the tokens
#logger.debug(refresh_token)
logout_request_data={"client_id": settings.SOCIAL_AUTH_KEYCLOAK_KEY, "refresh_token": refresh_token, "client_secret": settings.SOCIAL_AUTH_KEYCLOAK_SECRET}
headers={"Authorization" : "Bearer "+access_token,"Content-Type" : "application/x-www-form-urlencoded"}
result=requests.post(settings.SOCIAL_AUTH_KEYCLOAK_LOGOUT_URL,data=logout_request_data,headers=headers)
auth_logout(request)
return redirect('/')
result code will be 204 on success.

Updating Google Drive Metadata with googleapiclient in python

I am trying to update a Test file's metadata (specifically the file's name) in Google Drive using python's Google API client library. I have used the following google resources:
https://developers.google.com/drive/api/v3/reference/files/update
I haven't had had trouble connecting to googles drive API. I am merely having issues updating the filename or any other metadata that I would want to update.
My code is below:
from googleapiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
from googleapiclient import errors
from googleapiclient.http import MediaFileUpload
# This is to connect to Google Drive's API
SCOPES = 'https://www.googleapis.com/auth/drive.metadata' # drive.metadata gives me the access to read and writeover metadata
CLIENT_SECRET = 'client_id.json' # this is from Oauth when you create credentials for a good project
store = file.Storage('storage.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET, SCOPES)
creds = tools.run_flow(flow, store)
DRIVE = discovery.build('drive', 'v3', http=creds.authorize(Http()))
files = DRIVE.files().list().execute().get('files', [])
print()
print("File Specific metadata")
for f in files:
if f['name']=='Test' and f['mimeType']=='application/vnd.google-apps.document':
print(f['name'], f['id'], f['mimeType'])
file_id = f['id']
print(file_id)
# First retrieve the file from the API.
print()
file = DRIVE.files().get(fileId=file_id).execute()
print(file)
file['name'] = 'A'
print(file)
# Send the request to the API.
updated_file = DRIVE.files().update(fileId=file_id, body=file).execute()
But when I do this, I get an insufficient permissions error. I think it has something to do with the SCOPES but I am not sure.

Yahoo Fantasy Sports API Oauth Verifier Not Available

I'm trying to create a program in Python that uses data from Yahoo Fantasy Sports API (Football to be specific). I've already registered an desktop app on the Yahoo Developer Network in order to get permission to use OAuth. I've also gotten the correct urls, client key, and client secret and other necessary information to run the program.
Currently, I am using this website as a resource: https://requests-oauthlib.readthedocs.org/en/latest/oauth1_workflow.html
I managed to complete the get request token phase **, but am now stuck at the **authorization phase, requiring me to get an oauth token and oauth verifier i believe.
However, I'm only able to receive an oauth token, and the methods I call do not return an oauth verifier at all, making it impossible to proceed to the access token step. I'm just looking for some possibilities as to why this is the case.
Thanks.
import csv
import requests
import sys
import time
import webbrowser
from oauth_hook import OAuthHook
from requests_oauthlib import OAuth1Session
from requests_oauthlib import OAuth1
from urlparse import parse_qs
access_token_url = "https://api.login.yahoo.com/oauth/v2/get_token"
request_token_url = "https://api.login.yahoo.com/oauth/v2/get_request_token"
base_authorization_url = "https://api.login.yahoo.com/oauth/v2/request_auth"
callback_URL = "auto-manager.com"
client_key = ".." #can't reveal actual client stuff here
client_secret = ".."
#get request token
oauth = OAuth1Session(client_key,client_secret=client_secret)
print oauth
fetch_response = oauth.fetch_request_token(request_token_url)
resource_owner_key = fetch_response.get('oauth_token')
resource_owner_secret = fetch_response.get('oauth_token_secret')
print fetch_response
print resource_owner_key
print resource_owner_secret
# get authorization, returns no verifier but returns a token for some reason, PROBLEM's here
authorization_url = oauth.authorization_url(base_authorization_url)
print 'please go here and authorize,', authorization_url
redirect_response = raw_input('Paste full redirect URL here: ')
oauth_response = oauth.parse_authorization_response(redirect_response)
print oauth_response
The main issue i've found with requets_oauthlib is that it doesn't let you kind of customize stuff such as headers and body content. I've tried to use it for Yahoo OAuth but i got stuck because of that.
I turned to rauth, with which i managed to make things work. I even developed a special OAuth Lib for Yahoo which supports OAuth1 and OAuth2.
The lib is named yahoo-oauth.
Hope it will help you out.
Have a good one

Resources