Skip to content

Instantly share code, notes, and snippets.

@jhw
Last active June 29, 2024 08:35
Show Gist options
  • Save jhw/9c2df347a72aa279cb02a176c5ff3aa2 to your computer and use it in GitHub Desktop.
Save jhw/9c2df347a72aa279cb02a176c5ff3aa2 to your computer and use it in GitHub Desktop.
GCloud project to create OAuth creds + scopes + callbacks etc required to configure AWS Cognito UserPool for federated auth with Google

THIS DOESN'T WORK BECAUSE IT APPEARS YOU CAN'T GENERATE THE NECESSARY OAUTH STUFF PROGRAMATICALLY

*.pyc
__pycache__
env
tmp
import argparse
import google.auth
from google.auth.transport.requests import Request
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
import uuid
import time
def create_google_project(project_name):
try:
credentials, project = google.auth.default()
service = build('cloudresourcemanager', 'v1', credentials=credentials)
unique_id = str(uuid.uuid4())[:8]
base_project_id = project_name.lower().replace(' ', '-')[:21]
project_id = f"{base_project_id}-{unique_id}"
project_body = {
'projectId': project_id,
'name': project_name
}
request = service.projects().create(body=project_body)
operation = request.execute()
print('Project creation operation:')
print(operation)
# Poll the operation until it completes
operations_service = service.operations()
while not operation.get('done', False):
print('Waiting for operation to complete...')
time.sleep(5)
operation = operations_service.get(name=operation['name']).execute()
if 'error' in operation:
raise Exception(f"Error creating project: {operation['error']}")
print('Project created successfully.')
print(f'Project ID: {project_id}')
return project_id
except HttpError as err:
print(f'HTTP error occurred: {err}')
if err.resp.status == 400:
print('Details:', err.resp)
return None
except KeyError as key_err:
print(f'Key error: {key_err}')
return None
except Exception as ex:
print(f'Error: {ex}')
return None
def enable_service_api(project_id, service_name):
try:
credentials, project = google.auth.default()
service = build('serviceusage', 'v1', credentials=credentials)
request = service.services().enable(
name=f'projects/{project_id}/services/{service_name}'
)
response = request.execute()
print(f'Service {service_name} enabled:')
print(response)
return response
except HttpError as err:
print(f'HTTP error occurred while enabling {service_name}: {err}')
return None
def create_oauth_credentials(project_id, callback_urls):
try:
credentials, project = google.auth.default()
service = build('iam', 'v1', credentials=credentials)
oauth_body = {
'client_type': 'web',
'redirect_uris': callback_urls
}
request = service.projects().oauth2Clients().create(parent=f'projects/{project_id}', body=oauth_body)
response = request.execute()
return response
except HttpError as err:
print(f'HTTP error occurred: {err}')
return None
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Create a Google Cloud project and set up OAuth 2.0 credentials.')
parser.add_argument('project_name', type=str, help='The name of the Google Cloud project to create')
parser.add_argument('cognito_domain', type=str, help='The domain prefix of your AWS Cognito User Pool')
parser.add_argument('region', type=str, help='The AWS region where your Cognito User Pool is hosted')
args = parser.parse_args()
project_id = create_google_project(args.project_name)
if not project_id:
print('Failed to create Google Cloud project')
exit(1)
print('--- Project created successfully ---')
print(f'Project ID: {project_id}')
callback_url = f"https://{args.cognito_domain}.auth.{args.region}.amazoncognito.com/oauth2/idpresponse"
callback_urls = [callback_url]
# Enable necessary APIs
enable_service_api(project_id, 'cloudresourcemanager.googleapis.com')
enable_service_api(project_id, 'iam.googleapis.com')
oauth_response = create_oauth_credentials(project_id, callback_urls)
if not oauth_response:
print('Failed to create OAuth 2.0 credentials')
exit(1)
print('--- OAuth 2.0 credentials created successfully ---')
print('OAuth2 credentials:')
print(oauth_response)
print("\n---- OAuth Configuration for AWS Cognito ----")
print(f"Cognito Callback URL: {callback_url}")
print(f"Google Client ID: {oauth_response['client_id']}")
print(f"Google Client Secret: {oauth_response['client_secret']}")
print(f"Google Project ID: {project_id}")
print(f"Google Project Name: {args.project_name}")

Top level

https://cloud.google.com/?hl=en https://console.cloud.google.com/welcome Create Projects -> Polyreader OAuth Creds https://console.cloud.google.com/welcome?project=polyreader-oauth-creds

Enable APIs

https://console.cloud.google.com/apis/dashboard?project=polyreader-oauth-creds https://console.cloud.google.com/apis/library?project=polyreader-oauth-creds enable Cloud Resource Manager API enable Identity and Access Management (IAM) API

OAuth generation

https://console.cloud.google.com/apis/credentials?project=polyreader-oauth-creds

(you should see the APIs and Services menu on the LHS)

Configure consent screen

External Home page -> https://home.polyreader.net Authorised domain -> polyreader.net

Add scopes

openid: This scope is necessary for OpenID Connect (OIDC) authentication. email: This scope allows access to the user's email address. profile: This scope provides access to the user's profile information.

However, Google scopes are prefixed with the base URL for Google APIs, so you should use the following when explicitly entering full scopes:

OpenID: openid Email: https://www.googleapis.com/auth/userinfo.email Profile: https://www.googleapis.com/auth/userinfo.profile

You can use the filter screen and select, but will need to remove the filters to see everything that has been selected

Test users

Add your own email address

Credentials

Credentials -> Create Credentials -> Create OAuth client id Web application Authorised javascript origins -> https://polyreader.net Authorised redirect URIs -> https://polyreader.auth.eu-west-1.amazoncognito.com/oauth2/idpresponse Hit create and download creds

Testing and deployment

The message "OAuth access is restricted to the test users listed on your OAuth consent screen" appears because the OAuth consent screen is configured as an "External" application in "Testing" mode. In this mode, only the users you explicitly list as test users can access the OAuth application.

On the OAuth consent screen there is a "Publish App" button to make the app public

gcloud

gcloud projects list

listing and deleting 29/06/24

hw@Justins-MacBook-Air 9c2df347a72aa279cb02a176c5ff3aa2 % gcloud projects list 
PROJECT_ID                      NAME                      PROJECT_NUMBER
brave-watch-314519              My Project 64342          1031368902760
polyreader-oauth-cred-c0441394  polyreader-oauth-creds    209828398767
you-can-see-this-project        You can see this project  1084169201426
jhw@Justins-MacBook-Air 9c2df347a72aa279cb02a176c5ff3aa2 % gcloud projects delete 209828398767
Your project will be deleted.

Do you want to continue (Y/n)?  y

Deleted [https://cloudresourcemanager.googleapis.com/v1/projects/209828398767].

You can undo this operation for a limited period by running the command below.
    $ gcloud projects undelete 209828398767

See https://cloud.google.com/resource-manager/docs/creating-managing-projects for information on shutting down projects.
jhw@Justins-MacBook-Air 9c2df347a72aa279cb02a176c5ff3aa2 % gcloud projects list    

create project 29/06/24

(env) jhw@Justins-MacBook-Air 9c2df347a72aa279cb02a176c5ff3aa2 % python create_google_project.py polyreader-oauth-creds polyreader-auth eu-west-1
Traceback (most recent call last):
  File "/Users/jhw/work/gists/aws/9c2df347a72aa279cb02a176c5ff3aa2/create_google_project.py", line 60, in <module>
    project_id = create_google_project(args.project_name)
  File "/Users/jhw/work/gists/aws/9c2df347a72aa279cb02a176c5ff3aa2/create_google_project.py", line 9, in create_google_project
    credentials, project = google.auth.default()
  File "/Users/jhw/work/gists/aws/9c2df347a72aa279cb02a176c5ff3aa2/env/lib/python3.10/site-packages/google/auth/_default.py", line 691, in default
    raise exceptions.DefaultCredentialsError(_CLOUD_SDK_MISSING_CREDENTIALS)
google.auth.exceptions.DefaultCredentialsError: Your default credentials were not found. To set up Application Default Credentials, see https://cloud.google.com/docs/authentication/external/set-up-adc for more information.
(env) jhw@Justins-MacBook-Air 9c2df347a72aa279cb02a176c5ff3aa2 % deactivate 
jhw@Justins-MacBook-Air 9c2df347a72aa279cb02a176c5ff3aa2 % gcloud auth application-default login
Your browser has been opened to visit:

    https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8085%2F&scope=openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fsqlservice.login&state=IBcpYNHzy7dRasBFAO9SPZVEEYV5UJ&access_type=offline&code_challenge=NEIuWAU8AqseSSc20z9pK1DqZWJiREGZWCmBEPiLTxk&code_challenge_method=S256


Credentials saved to file: [/Users/jhw/.config/gcloud/application_default_credentials.json]

These credentials will be used by any library that requests Application Default Credentials (ADC).
WARNING: 
Cannot add the project "1084169201426" to ADC as the quota project because the account in ADC does not have the "serviceusage.services.use" permission on this project. You might receive a "quota_exceeded" or "API not enabled" error. Run $ gcloud auth application-default set-quota-project to add a quota project.
jhw@Justins-MacBook-Air 9c2df347a72aa279cb02a176c5ff3aa2 % gcloud auth list
     Credentialed Accounts
ACTIVE  ACCOUNT
*       justin.worrall@gmail.com

To set the active account, run:
    $ gcloud config set account `ACCOUNT`

jhw@Justins-MacBook-Air 9c2df347a72aa279cb02a176c5ff3aa2 % gcloud auth application-default print-access-token
ya29.a0AXooCgtSqanSC0wWqfnvyAcbjf29TxRooELIdY3j_2vxm3LqPF-c1NoFclFAFaR4rPHD9ESC-8fAaxYyF1TztQOybFGiUSvxhw6diOy6zEzMW5AUzspAFUm720LuWdamRuOo2bvp7M6yjVJynCnlJdhUrMHnSeInZXCLaCgYKAZ4SARASFQHGX2Mi8qRKzvAUehmbH6vibDAzPw0171
jhw@Justins-MacBook-Air 9c2df347a72aa279cb02a176c5ff3aa2 % 

packages 29/06/24

pip install google-api-python-client google-auth google-auth-oauthlib google-auth-httplib2

resources 28/06/24

https://chatgpt.com/c/c52071aa-8d73-4501-89b3-41a14ca2c32c

Google 28/06/24

https://cloud.google.com/sdk/docs/install-sdk

gcloud config configurations list
gcloud config configurations create <configuration-name>
gcloud config configurations activate <configuration-name>

gcloud config set project <project-id>
gcloud config set compute/region <region>
gcloud config set compute/zone <zone>

gcloud config list
google-api-python-client
google-auth
google-auth-oauthlib
google-auth-httplib2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment