Skip to content

Conversation

@ScruffyProdigy
Copy link
Contributor

No description provided.

@ScruffyProdigy ScruffyProdigy requested a review from a team as a code owner November 19, 2020 00:26
@google-cla google-cla bot added the cla: yes This human has signed the Contributor License Agreement. label Nov 19, 2020
@ScruffyProdigy ScruffyProdigy changed the title Adding support for url-based credential files feat: Adding support for url-based credential files Nov 19, 2020
@ScruffyProdigy ScruffyProdigy changed the title feat: Adding support for url-based credential files feat: adding support for url-based credential files Nov 19, 2020
Copy link
Contributor

@bojeil-google bojeil-google left a comment

Choose a reason for hiding this comment

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

Thanks for making the changes.

Summary of feedback:

  • headers need to be honored.
  • urllib not needed. request can be used instead and is provided in the retrieve_subject_token()
  • More test coverage.

client_secret=None,
quota_project_id=None,
scopes=None,
success_codes=(http_client.OK,),
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do you need this? This can be hardcoded below. Since this is publicly available, we don't want to expose it.

return file_obj.read(), filename

def _get_url_data(self, url):
response = urllib.request.urlopen(url)
Copy link
Contributor

Choose a reason for hiding this comment

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

You need to also honor the headers field when sending the request.

return file_obj.read(), filename

def _get_url_data(self, url):
response = urllib.request.urlopen(url)
Copy link
Contributor

Choose a reason for hiding this comment

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

You don't need to use urllib. You already have an instance of request in retrieve_subject_token(). Pass it through.

    def _get_token_url(self, request, url, headers):
        response = request(
            url=url,
            method="GET",
            headers=headers
        )

        # support both string and bytes type response.data
        response_body = (
            response.data.decode("utf-8")
            if hasattr(response.data, "decode")
            else response.data
        )

        if response.status != 200:
            raise exceptions.RefreshError(
                "Unable to retrieve Identity Pool subject token",
                response_body
            )

        return response_body

from google.auth import exceptions
from google.auth import external_account
from six.moves import http_client
from six.moves import urllib
Copy link
Contributor

Choose a reason for hiding this comment

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

Check below. You don't need urllib or http_client.

)
)

@mock.patch.object(urllib.request, "urlopen", return_value=FakeResponse(
Copy link
Contributor

Choose a reason for hiding this comment

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

We need more tests. We will need to cover the following test cases (some you already covered):

  • test_from_info_full_options but with url sourced credential_source
  • test_from_file_full_options but with url sourced credential_source
  • test_retrieve_subject_token but from url with raw text format
  • test_retrieve_subject_token but from url with json format
  • test_retrieve_subject_token but from url with invalid field name
  • test_retrieve_subject_token but from url with invalid json response
  • test_retrieve_subject_token but with url error (non-200 response)
  • test_refresh with url-sourced cred without service account impersonation
  • test_refresh with url-sourced cred with service account impersonation
  • test_refresh with url-sourced cred error such as non-200 response.

Copy link
Contributor

@bojeil-google bojeil-google left a comment

Choose a reason for hiding this comment

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

Forgot to mention, the file description and public function comments need to be updated to cover url-source credentials.

Copy link
Contributor

@bojeil-google bojeil-google left a comment

Choose a reason for hiding this comment

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

Thanks for making the changes! This is looking really good. Just a few nits and minor change requests. Should be easy to resolve.

ID tokens) retrieved from a file location, typical for K8s workloads
registered with Hub with Hub workload identity enabled.
registered with Hub with Hub workload identity enabled, or retrieved from an
url, typical for AWS and Azure based workflows.
Copy link
Contributor

Choose a reason for hiding this comment

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

Since we have a dedicated credentials class for AWS, let's exclude AWS:

url, typical for Azure based workflows.

subject_token = credentials.retrieve_subject_token(
self.make_mock_request(token_data=JSON_FILE_CONTENT))

assert subject_token == JSON_FILE_SUBJECT_TOKEN
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you also assert the request was sent with the expected parameters? eg. the expected URL, GET method and headers and no body? We don't have any coverage for this at the moment.

with pytest.raises(exceptions.RefreshError) as excinfo:
credentials.retrieve_subject_token(
self.make_mock_request(
token_status=500,
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: since this is a not found error, maybe we can use 404?

"url": "http://fakeurl.com",
}
credentials = self.make_credentials(credential_source=credential_source)
with pytest.raises(exceptions.RefreshError) as excinfo:
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you assert the error message too?

):
assert request_kwargs["url"] == url
assert request_kwargs["method"] == "GET"
assert request_kwargs["headers"] is None
Copy link
Contributor

Choose a reason for hiding this comment

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

We still need a test with non-none headers. eg:

  "credential_source": {
    "url": "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=...",
    "headers": {
      "Metadata": "True"
    },
    "format": {
      "type": "json",
      "subject_token_field_name": "access_token"
    }
  }

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.

Mostly LGTM, just left a few docs-related asks.

@busunkim96 busunkim96 added automerge Merge the pull request once unit tests and other checks pass. kokoro:force-run Add this label to force Kokoro to re-run the tests. labels Dec 11, 2020
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Dec 11, 2020
@gcf-merge-on-green
Copy link

Merge-on-green attempted to merge your PR for 6 hours, but it was not mergeable because either one of your required status checks failed, one of your required reviews was not approved, or there is a do not merge label. Learn more about your required status checks here: https://help.github.com/en/github/administering-a-repository/enabling-required-status-checks. You can remove and reapply the label to re-run the bot.

@gcf-merge-on-green gcf-merge-on-green bot removed the automerge Merge the pull request once unit tests and other checks pass. label Dec 11, 2020
@busunkim96 busunkim96 added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Dec 11, 2020
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Dec 11, 2020
@busunkim96
Copy link
Contributor

@ScruffyProdigy If you join the googleapis org CI will run for you automatically.

@busunkim96 busunkim96 merged commit 2bd9e83 into googleapis:byoid Dec 11, 2020
@ScruffyProdigy ScruffyProdigy deleted the url-support branch December 11, 2020 20:40
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.

4 participants