Commit d86841e2 authored by Robert Ma's avatar Robert Ma Committed by Commit Bot

[Import Notifier] Get Monorail OAuth token from luci-auth

The application default credential belongs to the default Swarming bot
account, not the dedicated service account for wpt-importer. As
suggested by LUCI task force, we need to use `luci-auth token` instead.

Bug: 790503
Change-Id: I3257db9a49196fd427c6f2371d00dcabab7ee3a6
Reviewed-on: https://chromium-review.googlesource.com/c/1315931
Commit-Queue: Robert Ma <robertma@chromium.org>
Reviewed-by: default avatarQuinten Yearsley <qyearsley@chromium.org>
Cr-Commit-Position: refs/heads/master@{#605746}
parent d32c33c2
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""An interface to luci-auth.
The main usage is to get the OAuth access token for the service account on LUCI.
"""
class LuciAuth(object):
def __init__(self, host):
self._host = host
def get_access_token(self):
# ScriptError will be raised if luci-auth fails.
output = self._host.executive.run_command(['luci-auth', 'token'])
return output.strip()
...@@ -16,6 +16,7 @@ from collections import defaultdict ...@@ -16,6 +16,7 @@ from collections import defaultdict
import logging import logging
import re import re
from blinkpy.common.net.luci_auth import LuciAuth
from blinkpy.common.path_finder import PathFinder from blinkpy.common.path_finder import PathFinder
from blinkpy.w3c.common import WPT_GH_URL from blinkpy.w3c.common import WPT_GH_URL
from blinkpy.w3c.directory_owners_extractor import DirectoryOwnersExtractor from blinkpy.w3c.directory_owners_extractor import DirectoryOwnersExtractor
...@@ -35,6 +36,7 @@ class ImportNotifier(object): ...@@ -35,6 +36,7 @@ class ImportNotifier(object):
self.git = chromium_git self.git = chromium_git
self.local_wpt = local_wpt self.local_wpt = local_wpt
self._monorail_api = MonorailAPI
self.default_port = host.port_factory.get() self.default_port = host.port_factory.get()
self.finder = PathFinder(host.filesystem) self.finder = PathFinder(host.filesystem)
self.owners_extractor = DirectoryOwnersExtractor(host.filesystem) self.owners_extractor = DirectoryOwnersExtractor(host.filesystem)
...@@ -56,9 +58,8 @@ class ImportNotifier(object): ...@@ -56,9 +58,8 @@ class ImportNotifier(object):
patchset: The patchset number of the import CL (a string). patchset: The patchset number of the import CL (a string).
dry_run: If True, no bugs will be actually filed to crbug.com. dry_run: If True, no bugs will be actually filed to crbug.com.
service_account_key_json: The path to a JSON private key of a service_account_key_json: The path to a JSON private key of a
service account for accessing Monorail. If None, try to load service account for accessing Monorail. If None, try to get an
from the default location, i.e. the path stored in the access token from luci-auth.
environment variable GOOGLE_APPLICATION_CREDENTIALS.
Note: "test names" are paths of the tests relative to LayoutTests. Note: "test names" are paths of the tests relative to LayoutTests.
""" """
...@@ -265,7 +266,10 @@ class ImportNotifier(object): ...@@ -265,7 +266,10 @@ class ImportNotifier(object):
_log.info('[%d] Filed bug: %s', index, MonorailIssue.crbug_link(response['id'])) _log.info('[%d] Filed bug: %s', index, MonorailIssue.crbug_link(response['id']))
def _get_monorail_api(self, service_account_key_json): def _get_monorail_api(self, service_account_key_json):
return MonorailAPI(service_account_key_json=service_account_key_json) if service_account_key_json:
return self._monorail_api(service_account_key_json=service_account_key_json)
token = LuciAuth(self.host).get_access_token()
return self._monorail_api(access_token=token)
class TestFailure(object): class TestFailure(object):
......
...@@ -199,6 +199,18 @@ class ImportNotifierTest(unittest.TestCase): ...@@ -199,6 +199,18 @@ class ImportNotifierTest(unittest.TestCase):
self.notifier._get_monorail_api = unreachable # pylint: disable=protected-access self.notifier._get_monorail_api = unreachable # pylint: disable=protected-access
self.notifier.file_bugs([], True) self.notifier.file_bugs([], True)
def test_file_bugs_calls_luci_auth(self):
test = self
class FakeAPI(object):
def __init__(self, service_account_key_json=None, access_token=None):
test.assertIsNone(service_account_key_json)
test.assertEqual(access_token, 'MOCK output of child process')
self.notifier._monorail_api = FakeAPI # pylint: disable=protected-access
self.notifier.file_bugs([], False)
self.assertEqual(self.host.executive.calls, [['luci-auth', 'token']])
class TestFailureTest(unittest.TestCase): class TestFailureTest(unittest.TestCase):
......
...@@ -98,14 +98,14 @@ class MonorailAPI(object): ...@@ -98,14 +98,14 @@ class MonorailAPI(object):
'https://monorail-prod.appspot.com/_ah/api/discovery/v1/apis/' 'https://monorail-prod.appspot.com/_ah/api/discovery/v1/apis/'
'{api}/{apiVersion}/rest') '{api}/{apiVersion}/rest')
def __init__(self, service_account_key_json=None): def __init__(self, service_account_key_json=None, access_token=None):
"""Initializes a MonorailAPI instance. """Initializes a MonorailAPI instance.
Args: Args:
service_account_key_json: The path to a JSON private key of a service_account_key_json: The path to a JSON private key of a
service account for accessing Monorail. If None, try to load service account for accessing Monorail. If None, use access_token.
from the default location, i.e. the path stored in the access_token: An OAuth access token. If None, fall back to Google
environment variable GOOGLE_APPLICATION_CREDENTIALS. application default credentials.
""" """
# Make it easier to mock out the two libraries in the future. # Make it easier to mock out the two libraries in the future.
# Dependencies managed by wpt-import.vpython - pylint: disable=import-error,no-member # Dependencies managed by wpt-import.vpython - pylint: disable=import-error,no-member
...@@ -114,8 +114,13 @@ class MonorailAPI(object): ...@@ -114,8 +114,13 @@ class MonorailAPI(object):
import oauth2client.client import oauth2client.client
self._oauth2_client = oauth2client.client self._oauth2_client = oauth2client.client
# TODO(robertma): Deprecate the JSON key support once BuildBot is gone.
if service_account_key_json: if service_account_key_json:
credentials = self._oauth2_client.GoogleCredentials.from_stream(service_account_key_json) credentials = self._oauth2_client.GoogleCredentials.from_stream(service_account_key_json)
elif access_token:
credentials = self._oauth2_client.AccessTokenCredentials(
access_token=access_token,
user_agent='blinkpy/1.0')
else: else:
credentials = self._oauth2_client.GoogleCredentials.get_application_default() credentials = self._oauth2_client.GoogleCredentials.get_application_default()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment