diff --git a/src/definitions/lightspeed.ts b/src/definitions/lightspeed.ts index 60ab48918..e04567e44 100644 --- a/src/definitions/lightspeed.ts +++ b/src/definitions/lightspeed.ts @@ -65,6 +65,7 @@ export const LIGHTSPEED_SUGGESTION_COMPLETION_URL = `${LIGHTSPEED_API_VERSION}/a export const LIGHTSPEED_SUGGESTION_FEEDBACK_URL = `${LIGHTSPEED_API_VERSION}/ai/feedback/`; export const LIGHTSPEED_SUGGESTION_CONTENT_MATCHES_URL = `${LIGHTSPEED_API_VERSION}/ai/contentmatches/`; export const LIGHTSPEED_ME_AUTH_URL = `/api/${LIGHTSPEED_API_VERSION}/me/`; +export const LIGHTSPEED_MARKDOWN_ME_AUTH_URL = `/api/${LIGHTSPEED_API_VERSION}/me/summary/`; export const LIGHTSPEED_FEEDBACK_FORM_URL = "https://red.ht/ansible-ai-feedback"; diff --git a/src/features/lightspeed/explorerWebviewViewProvider.ts b/src/features/lightspeed/explorerWebviewViewProvider.ts index fd10bcbf7..e1371b07e 100644 --- a/src/features/lightspeed/explorerWebviewViewProvider.ts +++ b/src/features/lightspeed/explorerWebviewViewProvider.ts @@ -14,7 +14,6 @@ import { } from "./utils/explorerView"; import { LightspeedUser } from "./lightspeedUser"; -import { getLoggedInUserDetails } from "./utils/webUtils"; import { isPlaybook } from "./playbookExplanation"; export class LightspeedExplorerWebviewViewProvider @@ -69,22 +68,14 @@ export class LightspeedExplorerWebviewViewProvider } private async _getWebviewContent(webview: Webview, extensionUri: Uri) { - const userDetails = - await this.lightspeedAuthenticatedUser.getLightspeedUserDetails(false); - if (userDetails) { - const sessionInfo = getLoggedInUserDetails(userDetails); - const userName = userDetails.displayNameWithUserType; - const userType = sessionInfo.userInfo?.userType || ""; - const userRole = - sessionInfo.userInfo?.role !== undefined - ? sessionInfo.userInfo?.role - : ""; + const content = + await this.lightspeedAuthenticatedUser.getLightspeedUserContent(); + + if (content !== "undefined") { return getWebviewContentWithActiveSession( webview, extensionUri, - userName, - userType, - userRole, + String(content), this.hasPlaybookOpened(), ); } else { diff --git a/src/features/lightspeed/lightspeedUser.ts b/src/features/lightspeed/lightspeedUser.ts index cd994908e..96d4de757 100644 --- a/src/features/lightspeed/lightspeedUser.ts +++ b/src/features/lightspeed/lightspeedUser.ts @@ -4,8 +4,10 @@ import { ANSIBLE_LIGHTSPEED_AUTH_ID, getBaseUri, getUserTypeLabel, + getLoggedInUserDetails, } from "./utils/webUtils"; import { + LIGHTSPEED_MARKDOWN_ME_AUTH_URL, LIGHTSPEED_ME_AUTH_URL, LightSpeedCommands, } from "../../definitions/lightspeed"; @@ -17,6 +19,7 @@ import { isSupportedCallback, } from "./lightSpeedOAuthProvider"; import { Log } from "../../utils/logger"; +import * as marked from "marked"; export class LightspeedAccessDenied extends Error { constructor(message: string) { @@ -54,6 +57,7 @@ export class LightspeedUser { private _userDetails: LightspeedUserDetails | undefined; private _logger: Log; private _extensionHost: ExtensionHostType; + private _markdownUserDetails: string | undefined; constructor( private readonly context: vscode.ExtensionContext, @@ -136,6 +140,45 @@ export class LightspeedUser { } } + public async getUserInfoFromMarkdown(token: string) { + this._logger.info( + "[ansible-lightspeed-user] Sending request for logged-in user info...", + ); + + try { + const { data } = await axios.get( + `${getBaseUri(this._settingsManager)}${LIGHTSPEED_MARKDOWN_ME_AUTH_URL}`, + { + headers: { + Authorization: `Bearer ${token}`, + }, + }, + ); + + const markdownData = marked.parse(data.content) as string; + + return markdownData; + } catch (error) { + if ( + axios.isAxiosError(error) && + error.response && + error.response.status === 401 + ) { + throw new LightspeedAccessDenied(error.message); + } else if (axios.isAxiosError(error)) { + this._logger.error( + `[ansible-lightspeed-user] error message: ${error.message}`, + ); + throw new Error(error.message); + } else { + this._logger.error( + `[ansible-lightspeed-user] unexpected error: ${error}`, + ); + throw new Error("An unexpected error occurred"); + } + } + } + public async getAuthProviderOrder() { // NOTE: We can't gate this check on if this extension is active, // because it only activates on an authentication request. @@ -234,6 +277,16 @@ export class LightspeedUser { ); this._session = session; + let markdownUserInfo: string = ""; + try { + markdownUserInfo = await this.getUserInfoFromMarkdown( + session.accessToken, + ); + } catch (error) { + markdownUserInfo = ""; + } + this._markdownUserDetails = markdownUserInfo; + const displayName = userinfo.external_username || userinfo.username || ""; const userTypeLabel = getUserTypeLabel( @@ -271,12 +324,14 @@ export class LightspeedUser { this._session = undefined; this._userDetails = undefined; + this._markdownUserDetails = undefined; this._userType = undefined; } public async refreshLightspeedUser() { this._session = undefined; this._userDetails = undefined; + this._markdownUserDetails = undefined; await this.setLightspeedUser(false); } @@ -300,6 +355,59 @@ export class LightspeedUser { return this._userDetails; } + public async getMarkdownLightspeedUserDetails( + createIfNone: boolean, + useProviderType: AuthProviderType | undefined = undefined, + ) { + // Ensure we don't try to get a lightspeed auth session when the provider is not initialized + if (!this._settingsManager.settings.lightSpeedService.enabled) { + return undefined; + } + if ( + this._markdownUserDetails && + (!useProviderType || useProviderType === this._userType) + ) { + return this._markdownUserDetails; + } + + await this.setLightspeedUser(createIfNone, useProviderType); + + return this._markdownUserDetails; + } + + public async getLightspeedUserContent() { + // Ensure we don't try to get a lightspeed auth session when the provider is not initialized + if (!this._settingsManager.settings.lightSpeedService.enabled) { + return undefined; + } + + const markdownUserDetails = + await this.getMarkdownLightspeedUserDetails(false); + const userDetails = await this.getLightspeedUserDetails(false); + + let content = "undefined"; + if (markdownUserDetails !== "") { + content = String(markdownUserDetails); + } else { + if (userDetails) { + const sessionInfo = getLoggedInUserDetails(userDetails); + const userName = userDetails.displayNameWithUserType; + const userType = sessionInfo.userInfo?.userType || ""; + const userRole = + sessionInfo.userInfo?.role !== undefined + ? sessionInfo.userInfo?.role + : ""; + content = ` +
Logged in as: ${userName}
+User Type: ${userType}
+ ${userRole ? "Role: " + userRole : ""} + `; + } + } + + return content; + } + public async rhUserHasSeat(): Promise