Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for imersonated_credentials.Sign, IDToken #348

Merged
merged 7 commits into from
Aug 7, 2019
Merged

Add support for imersonated_credentials.Sign, IDToken #348

merged 7 commits into from
Aug 7, 2019

Conversation

salrashid123
Copy link
Contributor

Adds support for impersonated_credentials to sign and issue IDTokens.

impersonated_credentials uses IAMCredentials api at its core which also provides interfaces to generateIDToken() and signBlob():

This PR seesk to add support for those.

Some benefits:


The PR at the moment does not have sufficient test coverage (its a solid "C" at 75%). I'm unsure how to mock the internal request/responses since i used AuthorizedSession() internally within imersonated_credentials.py. Any tips or pointers there would let me add on coverage. I've left the anticipated responses i would like as comments in this current commit


Anyway, usage would be like this to sign and genrate ID tokens (i've verified the following works)

from google.oauth2 import id_token
from google.oauth2 import service_account
from google.auth import impersonated_credentials
import json
import google.auth
from google.auth import jwt
import google.auth.transport.requests
import base64
import os
from datetime import datetime, timedelta
from google.cloud import storage

from google.auth.transport.requests import AuthorizedSession


source_credentials = service_account.Credentials.from_service_account_file(
    '/path/to/svc.json')
target_scopes = ['https://www.googleapis.com/auth/cloud-platform']

target_credentials = impersonated_credentials.Credentials(
    source_credentials = source_credentials,
    target_principal='[email protected]',
    target_scopes = target_scopes,
    delegates=[],
    lifetime=300)

# =====================   Sign

# signer anything you want as the impersonated credentials
b = target_credentials.sign_bytes('badff')
print base64.b64encode(b)


storage_client = storage.Client('fabled-ray-104117', target_credentials)
data_bucket = storage_client.lookup_bucket('fabled-ray-104117')
signed_blob_path = data_bucket.blob("FILENAME")
expires_at_ms = 30 * 60 *60
print expires_at_ms
signed_url = signed_blob_path.generate_signed_url(expires_at_ms, credentials=target_credentials, version="v4")

print signed_url

# =====================   IDToken

target_audience = 'https://your.cloud.run.app'

id_creds = impersonated_credentials.IDTokenCredentials(
    target_credentials, target_audience=target_audience)

url = 'https://your.cloud.run.app'
authed_session = AuthorizedSession(id_creds)
r = authed_session.get(url)

@googlebot googlebot added the cla: yes This human has signed the Contributor License Agreement. label Jun 19, 2019
@salrashid123
Copy link
Contributor Author

@theacodes @busunkim96

Any pointers on how i can mock the embedded AuthorizedSession() (or for that matter, if i should even be using it in the implementation)? Once i get through that, i'll add on the other testcases for coverage

@yoshi-automation yoshi-automation added 🚨 This issue needs some love. and removed 🚨 This issue needs some love. labels Jun 26, 2019
@salrashid123
Copy link
Contributor Author

@theacodes @busunkim96
hi- Could we startoff the review cycle on this one? if we're awaiting coverage/tests to pass, i could stand to get a pointer to fix that.

@salrashid123
Copy link
Contributor Author

@theacodes Could we start on the review on this? As mentioned offline, i'm unsure about how to create the testcases that compount two request

Copy link
Contributor

@busunkim96 busunkim96 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your patience @salrashid123!

I left a few comments below and will get back to you tomorrow morning on the test cases. You can disregard the current test failure in Travis; it was because of a change to pytest (#353).

google/auth/impersonated_credentials.py Outdated Show resolved Hide resolved
tests/test_impersonated_credentials.py Outdated Show resolved Hide resolved
google/auth/impersonated_credentials.py Outdated Show resolved Hide resolved
Copy link
Contributor

@busunkim96 busunkim96 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more comments on raising test coverage

google/auth/impersonated_credentials.py Show resolved Hide resolved
google/auth/impersonated_credentials.py Show resolved Hide resolved
@salrashid123
Copy link
Contributor Author

@busunkim96
@JustinBeckwith
anything additional you'd like to add to the PR

@busunkim96 busunkim96 requested review from tswast and removed request for theacodes August 6, 2019 00:14
Copy link
Contributor

@busunkim96 busunkim96 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for all your patience @salrashid123.

@tswast, could you also take a look?

@salrashid123
Copy link
Contributor Author

ok, i'm gonna give one more round of end-to-end testing for all the modes later today (just to be sure).

Ill reply back here before final merge.

thanks for the reviews!

@salrashid123
Copy link
Contributor Author

verified the follwoing works with the final fileset in the last commit

from google.oauth2 import id_token
from google.oauth2 import service_account
from google.auth import impersonated_credentials
import json
import google.auth
from google.auth import jwt
import google.auth.transport.requests
import base64
import os
from datetime import datetime, timedelta

from google.auth.transport.requests import AuthorizedSession
from google.cloud import storage

source_credentials = service_account.Credentials.from_service_account_file(
    '/path/to/svc.json')
target_scopes = ['https://www.googleapis.com/auth/cloud-platform']

target_credentials = impersonated_credentials.Credentials(
    source_credentials = source_credentials,
    target_principal='[email protected]',
    target_scopes = target_scopes,
    delegates=[],
    lifetime=300)

# =====================   SignedURL


client = storage.Client("fabled-ray-104117", target_credentials )

bucket = client.get_bucket('fabled-ray-104117')
blob = bucket.get_blob('signed_url_file.txt')
s = blob.generate_signed_url(expiration=60, method="GET", version="v4")
print s


# =====================   IDToken

target_audience = 'https://myapp-6w42z6vi3q-uc.a.run.app'
id_creds = impersonated_credentials.IDTokenCredentials(
    target_credentials, target_audience=target_audience, include_email=False)

url = 'https://myapp-6w42z6vi3q-uc.a.run.app'
authed_session = AuthorizedSession(id_creds)
r = authed_session.get(url)

print r.status_code
print r.text

# verify
certs_url='https://www.googleapis.com/oauth2/v1/certs'
request = google.auth.transport.requests.Request()
idt = id_creds.token
print idt
print id_token.verify_token(idt,request,certs_url=certs_url)

docs/user-guide.rst Outdated Show resolved Hide resolved
@busunkim96 busunkim96 merged commit 7a8641a into googleapis:master Aug 7, 2019
@salrashid123 salrashid123 deleted the add-idtoken-signer-impersonated branch August 12, 2019 02:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants