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

Support insights device authorization flow #288

Merged
merged 11 commits into from
Nov 30, 2023

Conversation

abellotti
Copy link
Contributor

@abellotti abellotti commented Nov 3, 2023

feat(insights): Add support for device authorization

  • With the upcoming elimination of the basic auth authentication to Insights, we are adding support for the device authorization flow.

New Insights login usage:

$ poetry run qpc insights login
Insights login authorization requested
User Code: HLGR-QZIX
Authorization URL: https://sso.redhat.com/auth/realms/redhat-external/device?user_code=HLGR-QZIX
Waiting for login authorization ...
Login authorization successful.
$ 

Insights publishing error messages:

When never logged in:

$ poetry run qpc insights publish --input-file report.tar.gz
Must first login to authenticate
$

Other error messages:

  • Authorization token expired, please re-login to Insights
  • Corrupt Authorization token, please re-login to Insights
  • Invalid Authorization token, please re-login to Insights

Draft, things still to be done:

  • use the token generated for the publish
  • make sure proper messages are displayed (no token, expired token, etc.)
  • remove add_login functions no longer used
  • update man page for the new login usage
  • test on non-work notebook/system (i.e. without RH certs installed).
  • test on external system (outside RedHat).
  • support stage sso
  • log errors (sso connect errors/ json responses on errors).
  • add tests

Other changes that will be required:

  • camayoc
  • docs

Relates to JIRA: DISCOVERY-459
https://issues.redhat.com/browse/DISCOVERY-459

@abellotti abellotti marked this pull request as draft November 3, 2023 20:39
@abellotti abellotti force-pushed the support_insights_device_auth branch from 0a2d272 to 850ccc3 Compare November 7, 2023 01:26
@codecov-commenter
Copy link

codecov-commenter commented Nov 7, 2023

Codecov Report

Attention: 22 lines in your changes are missing coverage. Please review.

Comparison is base (db40f9c) 93.73% compared to head (2580ce0) 93.30%.
Report is 2 commits behind head on main.

❗ Current head 2580ce0 differs from pull request most recent head deaf91d. Consider uploading reports for the commit deaf91d to get more accurate results

Files Patch % Lines
qpc/insights/auth.py 90.24% 8 Missing ⚠️
qpc/insights/publish.py 74.07% 7 Missing ⚠️
qpc/utils.py 63.15% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #288      +/-   ##
==========================================
- Coverage   93.73%   93.30%   -0.44%     
==========================================
  Files          67       68       +1     
  Lines        2827     2927     +100     
==========================================
+ Hits         2650     2731      +81     
- Misses        177      196      +19     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@abellotti abellotti force-pushed the support_insights_device_auth branch 3 times, most recently from 4d6ea94 to b77e48c Compare November 10, 2023 20:48
@abellotti
Copy link
Contributor Author

Additional logging for Insights login and publishing. Normal output, additional Info (with -v) and Debugging (with -vv).

  • Login - Bad Request
$ poetry run qpc insights login
Failed to request login authorization: Bad Request
$ poetry run qpc -v insights login
Requesting Login authorization from https://sso.redhat.com//auth/realms/redhat-external/protocol/openid-connect/auth/device
Failed to request login authorization: Bad Request
$ poetry run qpc -vv insights login
2023-11-10 15:50:33,707 - qpc.utils - DEBUG - [log_args] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/utils.py:379 - Args: "Namespace(verbosity=2, subcommand='insights', action='login')"
2023-11-10 15:50:33,708 - qpc.insights.auth - INFO - [request_auth] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/insights/auth.py:51 - Requesting Login authorization from https://sso.redhat.com//auth/realms/redhat-external/protocol/openid-connect/auth/device
2023-11-10 15:50:33,839 - qpc.insights.auth - DEBUG - [request_auth] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/insights/auth.py:64 - Response from sso.redhat.com: {"error":"invalid_client","error_description":"Invalid client credentials"}
2023-11-10 15:50:33,839 - qpc.insights.login - ERROR - [_do_command] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/insights/login.py:50 - Failed to request login authorization: Bad Request
  • Login - Cannot connect to SSO
$ poetry run qpc insights login
Failed to request login authorization: HTTPSConnectionPool(host='badsso.redhat.com', port=443): Max retries exceeded with url: //auth/realms/redhat-external/protocol/openid-connect/auth/device (Caused by NameResolutionError("<urllib3.connection.HTTPSConnection object at 0x102237490>: Failed to resolve 'badsso.redhat.com' ([Errno 8] nodename nor servname provided, or not known)"))
$ poetry run qpc -v insights login
Requesting Login authorization from https://badsso.redhat.com//auth/realms/redhat-external/protocol/openid-connect/auth/device
Failed to request login authorization: HTTPSConnectionPool(host='badsso.redhat.com', port=443): Max retries exceeded with url: //auth/realms/redhat-external/protocol/openid-connect/auth/device (Caused by NameResolutionError("<urllib3.connection.HTTPSConnection object at 0x103bc97d0>: Failed to resolve 'badsso.redhat.com' ([Errno 8] nodename nor servname provided, or not known)"))
$ poetry run qpc -vv insights login
2023-11-10 16:05:15,913 - qpc.utils - DEBUG - [log_args] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/utils.py:379 - Args: "Namespace(verbosity=2, subcommand='insights', action='login')"
2023-11-10 16:05:15,913 - qpc.insights.auth - INFO - [request_auth] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/insights/auth.py:51 - Requesting Login authorization from https://badsso.redhat.com//auth/realms/redhat-external/protocol/openid-connect/auth/device
2023-11-10 16:05:15,919 - qpc.insights.login - ERROR - [_do_command] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/insights/login.py:50 - Failed to request login authorization: HTTPSConnectionPool(host='badsso.redhat.com', port=443): Max retries exceeded with url: //auth/realms/redhat-external/protocol/openid-connect/auth/device (Caused by NameResolutionError("<urllib3.connection.HTTPSConnection object at 0x103eb5c10>: Failed to resolve 'badsso.redhat.com' ([Errno 8] nodename nor servname provided, or not known)"))
  • Login - Happy Path
$ poetry run qpc insights login
Insights login authorization requested
User Code: NMDN-FRYP
Authorization URL: https://sso.redhat.com/auth/realms/redhat-external/device?user_code=NMDN-FRYP
Waiting for login authorization ...
$ poetry run qpc -v insights login
Requesting Login authorization from https://sso.redhat.com//auth/realms/redhat-external/protocol/openid-connect/auth/device
Insights login authorization requested
User Code: XQVK-YSQX
Authorization URL: https://sso.redhat.com/auth/realms/redhat-external/device?user_code=XQVK-YSQX
Waiting for login authorization ...
$ poetry run qpc -vv insights login
2023-11-10 16:06:55,770 - qpc.utils - DEBUG - [log_args] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/utils.py:379 - Args: "Namespace(verbosity=2, subcommand='insights', action='login')"
2023-11-10 16:06:55,770 - qpc.insights.auth - INFO - [request_auth] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/insights/auth.py:51 - Requesting Login authorization from https://sso.redhat.com//auth/realms/redhat-external/protocol/openid-connect/auth/device
2023-11-10 16:06:55,950 - qpc.insights.auth - DEBUG - [request_auth] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/insights/auth.py:60 - Response from sso.redhat.com: {'device_code': 'AonSTQusKqpEvVPUrTfpuJkhPhmRzxZKUi2yrQMoC3E', 'user_code': 'GGDA-INWW', 'verification_uri': 'https://sso.redhat.com/auth/realms/redhat-external/device', 'verification_uri_complete': 'https://sso.redhat.com/auth/realms/redhat-external/device?user_code=GGDA-INWW', 'expires_in': 600, 'interval': 5}
Insights login authorization requested
User Code: GGDA-INWW
Authorization URL: https://sso.redhat.com/auth/realms/redhat-external/device?user_code=GGDA-INWW
Waiting for login authorization ...
2023-11-10 16:06:55,952 - qpc.insights.auth - DEBUG - [wait_for_authorization] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/insights/auth.py:95 - Verifying Login authorization at https://sso.redhat.com//auth/realms/redhat-external/protocol/openid-connect/token
2023-11-10 16:06:56,067 - qpc.insights.auth - DEBUG - [wait_for_authorization] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/insights/auth.py:125 - Response from sso.redhat.com: {'error': 'authorization_pending', 'error_description': 'The authorization request is still pending'}
2023-11-10 16:07:01,072 - qpc.insights.auth - DEBUG - [wait_for_authorization] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/insights/auth.py:95 - Verifying Login authorization at https://sso.redhat.com//auth/realms/redhat-external/protocol/openid-connect/token
2023-11-10 16:07:01,226 - qpc.insights.auth - DEBUG - [wait_for_authorization] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/insights/auth.py:125 - Response from sso.redhat.com: {'error': 'authorization_pending', 'error_description': 'The authorization request is still pending'}
  • Publish - Happy Path
$ poetry run qpc insights publish --input report.tar.gz 
{"request_id":"0c5b30af8b01408d87bb17382ca8e35b","upload":{"account_number":"1460290","org_id":"6340056"}}
$ poetry run qpc -v insights publish --input report.tar.gz 
Publishing report to Insights at https://console.redhat.com:443/api/ingress/v1/upload
Response from insights: {"request_id":"831ce7fdf3f04e2d98db0fafb29f9a3e","upload":{"account_number":"1460290","org_id":"6340056"}}
The report was successfully published.
{"request_id":"831ce7fdf3f04e2d98db0fafb29f9a3e","upload":{"account_number":"1460290","org_id":"6340056"}}
  • Publish - Cannot connect to Console
$ poetry run qpc insights publish --input-file report.tar.gz
Failed to publish the report to Insights: HTTPSConnectionPool(host='badconsole.redhat.com', port=443): Max retries exceeded with url: /api/ingress/v1/upload (Caused by NameResolutionError("<urllib3.connection.HTTPSConnection object at 0x1068f8f10>: Failed to resolve 'badconsole.redhat.com' ([Errno 8] nodename nor servname provided, or not known)"))
$ poetry run qpc -v insights publish --input-file report.tar.gz
Publishing report to Insights at https://badconsole.redhat.com:443/api/ingress/v1/upload
Failed to publish the report to Insights: HTTPSConnectionPool(host='badconsole.redhat.com', port=443): Max retries exceeded with url: /api/ingress/v1/upload (Caused by NameResolutionError("<urllib3.connection.HTTPSConnection object at 0x1022f5250>: Failed to resolve 'badconsole.redhat.com' ([Errno 8] nodename nor servname provided, or not known)"))
$ poetry run qpc -vv insights publish --input-file report.tar.gz
2023-11-10 15:20:11,065 - qpc.utils - DEBUG - [log_args] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/utils.py:379 - Args: "Namespace(verbosity=2, subcommand='insights', action='publish', input_file='report.tar.gz', report=None)"
2023-11-10 15:20:11,097 - qpc.insights.publish - INFO - [_make_publish_request] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/insights/publish.py:200 - Publishing report to Insights at https://badconsole.redhat.com:443/api/ingress/v1/upload
2023-11-10 15:20:11,113 - qpc.insights.publish - ERROR - [_make_publish_request] - /Users/abellotti/DevHome/projects/discovery/qpc/qpc/insights/publish.py:207 - Failed to publish the report to Insights: HTTPSConnectionPool(host='badconsole.redhat.com', port=443): Max retries exceeded with url: /api/ingress/v1/upload (Caused by NameResolutionError("<urllib3.connection.HTTPSConnection object at 0x1042bd350>: Failed to resolve 'badconsole.redhat.com' ([Errno 8] nodename nor servname provided, or not known)"))

@abellotti
Copy link
Contributor Author

abellotti commented Nov 14, 2023

Adding support for staging sso server for the Device authorization workflow. SSO server defaults to sso.redhat.com but can be configured to others, i.e. sso.stage.redhat.com via the qpc insights config sub-command as follows:

$ poetry run qpc insights config --help
usage: qpc insights config [-h] [--host HOST] [--port PORT] [--use-http] [--sso-host SSO_HOST]

options:
  -h, --help           show this help message and exit
  --host HOST          Host or IP address.
  --port PORT          Port number.
  --use-http
  --sso-host SSO_HOST  Insights SSO Host
$ poetry run qpc insights config --sso-host sso.stage.redhat.com
$ cat ~/.config/qpc/insights.config
{
    "host": "console.redhat.com",
    "port": 443,
    "use_http": false,
    "sso_host": "sso.stage.redhat.com"
}
$ poetry run qpc insights login
Insights login authorization requested
User Code: MSSC-JXFI
Authorization URL: https://sso.stage.redhat.com/auth/realms/redhat-external/device?user_code=MSSC-JXFI
Waiting for login authorization ...
Login authorization successful.

@abellotti abellotti force-pushed the support_insights_device_auth branch 8 times, most recently from c2c9091 to 2580ce0 Compare November 20, 2023 20:30
@abellotti abellotti marked this pull request as ready for review November 20, 2023 20:33
qpc/insights/auth.py Outdated Show resolved Hide resolved
qpc/insights/auth.py Outdated Show resolved Hide resolved
@abellotti abellotti force-pushed the support_insights_device_auth branch 2 times, most recently from deaf91d to 79b65f1 Compare November 28, 2023 01:27
With the upcoming elimination of the basic auth authentication
to Insights, we are adding support for the device authorization
flow.

- Remove the insight add_login cli command
- Add support for the insights login cli command
- Add utilities to read and write the insight's user JWT authentication token
- Remove the add_login cli command tests
- Add the insights device authorization workflow
- updated the insights login command to request an authorization workflow
  and wait for the user to login/authorize out-of-band.
- fixed an issue with writing the auth token to file.
- When publishing reports to Insights, use the user's JWT authentication
  token for Authorization.
- Properly detect missing, corrupt, invalid and expired token cases.
- Removing all references to the insights login config file
  and related username/password handling logic and tests.
- Updated the man page to describe the login device authorization flow
  and the new qpc insights login subcommands.
…shing

- Improved logging for Insights login authorization and report publishing
- Added both logger.info (-v) and more detailed logger.debug (-vv) messages
  depicting target Insights SSO and Console server as well as response errors.
- Configurable via poetry run qpc insights config --sso-host <value>
- Defaults to sso.redhat.com
- Can be updated to the staging sso.stage.redhat.com
- Used by the device auth workflow
- Tests the new device auth workflow with insights login
- Tests for Insights Auth request_auth
- Tests for Insights Auth wait_for_authorization
- Support device auth workflow token timeout from the
  SSO server. These errors should result in the same exception
  we trigger upon expiration timeout checks.
- While these have not changed for a long time, it is always a good idea
  to fetch the device_authorization_endpoint and token_endpoint from
  the Keycloak OpenID well-known configuration json.
- Preferring to do a patch.object on sys.argv instead of overwriting
  the argument list.
- Using get defaults instead of or for expires_in and interval.
- Rebasing with main/updated rst manpage generation
@abellotti abellotti force-pushed the support_insights_device_auth branch from 79b65f1 to 9b29ecb Compare November 28, 2023 23:21
Copy link
Member

@infinitewarp infinitewarp left a comment

Choose a reason for hiding this comment

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

👍

@abellotti abellotti merged commit 01405ca into main Nov 30, 2023
6 checks passed
@abellotti abellotti deleted the support_insights_device_auth branch November 30, 2023 21:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants