From 4517575bef3f0f49a73458a3e72ac391de170c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A9ri=20Le=20Bouder?= Date: Sat, 9 Dec 2023 16:08:50 -0500 Subject: [PATCH] lightspeed: use the code value from the 403 (#1024) * lightspeed: use the code value from the 403 The 403 error can now return a `code` value to specify the nature of the error. `permission_denied_wca_api_key_is_missing` is the first case we can get. The error happens when the access is denied because the user has a seat but the organization has not been fully configured yet. * Lightspeed: show an error when the WCA key is not set yet Handle the `permission_denied__org_not_ready_because_wca_not_configured` error and returns the following error to the user: ``` Contact your administrator to configure IBM watsonx Code Assistant model settings for your organization. ``` --------- Co-authored-by: Sorin Sbarnea --- src/features/lightspeed/api.ts | 18 ++++++++++++ .../lightspeed/lightSpeedOAuthProvider.ts | 28 ++++++++++++++++++- src/features/lightspeed/statusBar.ts | 9 +++++- src/features/lightspeed/utils/webUtils.ts | 2 ++ src/interfaces/lightspeed.ts | 2 +- 5 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/features/lightspeed/api.ts b/src/features/lightspeed/api.ts index d1d1666bf..02dba292d 100644 --- a/src/features/lightspeed/api.ts +++ b/src/features/lightspeed/api.ts @@ -150,6 +150,24 @@ export class LightSpeedAPI { vscode.window.showErrorMessage( `Model ID "${this.settingsManager.settings.lightSpeedService.model}" is invalid. Please contact your administrator.` ); + } else if ( + responseErrorData && + responseErrorData.hasOwnProperty("code") && + responseErrorData.code === + "permission_denied__org_ready_user_has_no_seat" + ) { + vscode.window.showErrorMessage( + `You do not have a licensed seat for Ansible Lightspeed and your organization is using the paid commercial service. Contact your Red Hat Organization's administrator for more information on how to get a licensed seat.` + ); + } else if ( + responseErrorData && + responseErrorData.hasOwnProperty("code") && + responseErrorData.code === + "permission_denied__org_not_ready_because_wca_not_configured" + ) { + vscode.window.showErrorMessage( + `Contact your administrator to configure IBM watsonx Code Assistant model settings for your organization.` + ); } else { vscode.window.showErrorMessage( `User not authorized to access Ansible Lightspeed.` diff --git a/src/features/lightspeed/lightSpeedOAuthProvider.ts b/src/features/lightspeed/lightSpeedOAuthProvider.ts index e9073781f..2c68425a0 100644 --- a/src/features/lightspeed/lightSpeedOAuthProvider.ts +++ b/src/features/lightspeed/lightSpeedOAuthProvider.ts @@ -132,6 +132,9 @@ export class LightSpeedAuthenticationProvider const identifier = uuid(); const userName = userinfo.external_username || userinfo.username || ""; + const rhOrgHasSubscription = userinfo.rh_org_has_subscription + ? userinfo.rh_org_has_subscription + : false; const rhUserHasSeat = userinfo.rh_user_has_seat ? userinfo.rh_user_has_seat : false; @@ -139,6 +142,8 @@ export class LightSpeedAuthenticationProvider let label = userName; if (rhUserHasSeat) { label += " (licensed)"; + } else if (rhOrgHasSubscription) { + label += " (no seat assigned)"; } else { label += " (Tech Preview)"; } @@ -172,7 +177,8 @@ export class LightSpeedAuthenticationProvider lightSpeedManager.statusBarProvider.statusBar.text = await lightSpeedManager.statusBarProvider.getLightSpeedStatusBarText( - rhUserHasSeat + rhUserHasSeat, + rhOrgHasSubscription ); lightSpeedManager.statusBarProvider.setLightSpeedStatusBarTooltip( @@ -630,4 +636,24 @@ export class LightSpeedAuthenticationProvider return false; } } + + public async rhOrgHasSubscription(): Promise { + const authSession = await this.getLightSpeedAuthSession(); + if (authSession === undefined) { + console.log( + "[ansible-lightspeed-oauth] User authentication session not found." + ); + return undefined; + } else if (authSession?.rhOrgHasSubscription) { + console.log( + `[ansible-lightspeed-oauth] User "${authSession?.account?.label}" has an Org with a subscription.` + ); + return true; + } else { + console.log( + `[ansible-lightspeed-oauth] User "${authSession?.account?.label}" does not have an Org with a subscription.` + ); + return false; + } + } } diff --git a/src/features/lightspeed/statusBar.ts b/src/features/lightspeed/statusBar.ts index 514468caa..f143e4dc9 100644 --- a/src/features/lightspeed/statusBar.ts +++ b/src/features/lightspeed/statusBar.ts @@ -52,14 +52,21 @@ export class LightspeedStatusBar { } public async getLightSpeedStatusBarText( - rhUserHasSeat?: boolean + rhUserHasSeat?: boolean, + rhOrgHasSubscription?: boolean ): Promise { let lightSpeedStatusbarText; if (rhUserHasSeat === undefined) { rhUserHasSeat = await this.lightSpeedAuthProvider.rhUserHasSeat(); } + if (rhOrgHasSubscription === undefined) { + rhOrgHasSubscription = + await this.lightSpeedAuthProvider.rhOrgHasSubscription(); + } if (rhUserHasSeat === true) { lightSpeedStatusbarText = "Lightspeed (licensed)"; + } else if (rhOrgHasSubscription === true && rhUserHasSeat === false) { + lightSpeedStatusbarText = "Lightspeed (no seat assigned)"; } else if (rhUserHasSeat === false) { lightSpeedStatusbarText = "Lightspeed (Tech Preview)"; } else { diff --git a/src/features/lightspeed/utils/webUtils.ts b/src/features/lightspeed/utils/webUtils.ts index 8d3acf3f3..9a6cfb01d 100644 --- a/src/features/lightspeed/utils/webUtils.ts +++ b/src/features/lightspeed/utils/webUtils.ts @@ -77,6 +77,8 @@ export function getLoggedInSessionDetails( const modelInfo: LightspeedSessionModelInfo = {}; if (sessionData.rhUserHasSeat) { userInfo.userType = "Licensed"; + } else if (sessionData.rhOrgHasSubscription && sessionData.rhUserHasSeat) { + userInfo.userType = "No seat assigned"; } else { userInfo.userType = "Tech Preview"; } diff --git a/src/interfaces/lightspeed.ts b/src/interfaces/lightspeed.ts index 1167eee0b..e9353b5f8 100644 --- a/src/interfaces/lightspeed.ts +++ b/src/interfaces/lightspeed.ts @@ -166,7 +166,7 @@ export interface IAdditionalContext { } export interface LightspeedSessionUserInfo { - userType?: "Licensed" | "Tech Preview"; + userType?: "Licensed" | "No seat assigned" | "Tech Preview"; role?: string; subscribed?: boolean; }