-
Notifications
You must be signed in to change notification settings - Fork 3.3k
[AppService] az appservice: Add function to retrieve users github personal access token #17826
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
Changes from all commits
bbe4cb0
8ef6bfd
cb846f4
9440185
b7801d6
4473316
fda252b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| # -------------------------------------------------------------------------------------------- | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for license information. | ||
| # -------------------------------------------------------------------------------------------- | ||
|
|
||
| from azure.cli.core.azclierror import (ValidationError, CLIInternalError, UnclassifiedUserFault) | ||
| from knack.log import get_logger | ||
|
|
||
| from ._constants import (GITHUB_OAUTH_CLIENT_ID, GITHUB_OAUTH_SCOPES) | ||
|
|
||
| logger = get_logger(__name__) | ||
|
|
||
|
|
||
| ''' | ||
| Get Github personal access token following Github oauth for command line tools | ||
| https://docs.github.com/en/developers/apps/authorizing-oauth-apps#device-flow | ||
| ''' | ||
|
|
||
|
|
||
| def get_github_access_token(cmd, scope_list=None): | ||
| if scope_list: | ||
| for scope in scope_list: | ||
| if scope not in GITHUB_OAUTH_SCOPES: | ||
| raise ValidationError("Requested github oauth scope is invalid") | ||
| scope_list = ' '.join(scope_list) | ||
|
|
||
| authorize_url = 'https://github.com/login/device/code' | ||
| authorize_url_data = { | ||
| 'scope': scope_list, | ||
| 'client_id': GITHUB_OAUTH_CLIENT_ID | ||
| } | ||
|
|
||
| import base64 | ||
| import json | ||
| import requests | ||
| import time | ||
| from urllib.parse import urlparse, parse_qs | ||
|
|
||
| try: | ||
| response = requests.post(authorize_url, data=authorize_url_data) | ||
| parsed_response = parse_qs(response.content.decode('ascii')) | ||
|
|
||
| device_code = parsed_response['device_code'][0] | ||
| user_code = parsed_response['user_code'][0] | ||
| verification_uri = parsed_response['verification_uri'][0] | ||
| interval = int(parsed_response['interval'][0]) | ||
| expires_in_seconds = int(parsed_response['expires_in'][0]) | ||
| logger.warning('Please navigate to %s and enter the user code %s to activate and ' | ||
| 'retrieve your github personal access token', verification_uri, user_code) | ||
|
|
||
| timeout = time.time() + expires_in_seconds | ||
| logger.warning("Waiting up to '%s' minutes for activation", str(expires_in_seconds // 60)) | ||
|
|
||
| confirmation_url = 'https://github.com/login/oauth/access_token' | ||
| confirmation_url_data = { | ||
| 'client_id': GITHUB_OAUTH_CLIENT_ID, | ||
| 'device_code': device_code, | ||
| 'grant_type': 'urn:ietf:params:oauth:grant-type:device_code' | ||
| } | ||
|
|
||
| pending = True | ||
| while pending: | ||
| time.sleep(interval) | ||
|
|
||
| if time.time() > timeout: | ||
| raise UnclassifiedUserFault('Activation did not happen in time. Please try again') | ||
|
|
||
| confirmation_response = requests.post(confirmation_url, data=confirmation_url_data) | ||
| parsed_confirmation_response = parse_qs(confirmation_response.content.decode('ascii')) | ||
|
|
||
| if 'error' in parsed_confirmation_response and parsed_confirmation_response['error'][0]: | ||
| if parsed_confirmation_response['error'][0] == 'slow_down': | ||
| interval += 5 # if slow_down error is received, 5 seconds is added to minimum polling interval | ||
| elif parsed_confirmation_response['error'][0] != 'authorization_pending': | ||
| pending = False | ||
|
|
||
| if 'access_token' in parsed_confirmation_response and parsed_confirmation_response['access_token'][0]: | ||
| return parsed_confirmation_response['access_token'][0] | ||
| except Exception as e: | ||
| raise CLIInternalError( | ||
| 'Error: {}. Please try again, or retrieve personal access token from the Github website'.format(e)) | ||
|
|
||
| raise UnclassifiedUserFault('Activation did not happen in time. Please try again') |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -117,6 +117,7 @@ pbr==5.3.1 | |
| portalocker==1.7.1 | ||
| psutil==5.8.0 | ||
| pycparser==2.19 | ||
| PyGithub==1.38 | ||
|
||
| PyJWT==1.7.1 | ||
| PyNaCl==1.4.0 | ||
| pyOpenSSL==19.0.0 | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -137,6 +137,7 @@ | |
| 'jsmin~=2.2.2', | ||
| 'jsondiff==1.2.0', | ||
| 'packaging~=20.9', | ||
| 'PyGithub==1.38', | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The pinned version causes problem when being installed with the latest
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I should have added it to this PR instead, it will be used in this one #18261. And yes we shouldn't pin, we can use ~= and unpin. Thanks for bringing this up
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you change the dependency to use |
||
| 'pytz==2019.1', | ||
| 'scp~=0.13.2', | ||
| 'semver==2.13.0', | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you share where this ID comes from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's an oauth app created by AppService CLI team: https://github.com/AzureAppServiceCLI
Is there an official Azure oauth app we can use, or should we stick to this one?