From 4709e2c95f10b5cca2dfe83267f7152e1c04932c Mon Sep 17 00:00:00 2001 From: GeekMasher Date: Mon, 30 Jun 2025 12:07:49 +0100 Subject: [PATCH] feat: Implement GitHub authentication flow and UI integration --- src/providers/uiProvider.ts | 227 ++++++++++++++++++++++++++++++++++ src/services/githubService.ts | 67 ++++++++++ 2 files changed, 294 insertions(+) diff --git a/src/providers/uiProvider.ts b/src/providers/uiProvider.ts index 8aeb14c..7eadf96 100644 --- a/src/providers/uiProvider.ts +++ b/src/providers/uiProvider.ts @@ -54,6 +54,9 @@ export class UiProvider implements vscode.WebviewViewProvider { case "loadConfig": this.loadConfiguration(); break; + case "loginWithGitHub": + this.loginWithGitHub(); + break; case "testConnection": this.testGitHubConnection(); break; @@ -165,6 +168,26 @@ export class UiProvider implements vscode.WebviewViewProvider { } this.logger.info("UiProvider", `Using threat model: ${threatModel}`); + // Check GitHub auth status + try { + const authStatus = await this._githubService.checkGitHubAuth(); + + // Send auth status to the WebUI + this._view?.webview.postMessage({ + command: "authStatus", + isAuthenticated: authStatus.isAuthenticated, + displayName: authStatus.displayName + }); + + if (authStatus.isAuthenticated) { + this.logger.info("UiProvider", `User is authenticated with GitHub as: ${authStatus.displayName}`); + } else { + this.logger.info("UiProvider", "User is not authenticated with GitHub"); + } + } catch (error) { + this.logger.warn("UiProvider", "Failed to check GitHub authentication status", error); + } + // Auto-select GitHub repository languages if no manual selection exists let languages = config.get("languages", []); if (languages.length === 0) { @@ -593,6 +616,70 @@ export class UiProvider implements vscode.WebviewViewProvider { } } + private async loginWithGitHub() { + this.logger.logServiceCall("UiProvider", "loginWithGitHub", "started"); + + try { + // Update UI to show authentication is in progress + this._view?.webview.postMessage({ + command: "authStarted", + message: "GitHub authentication in progress..." + }); + + // Call GitHub Service to authenticate + const success = await this._githubService.authenticateWithGitHub(); + + if (success) { + this.logger.logServiceCall("UiProvider", "loginWithGitHub", "completed"); + + try { + // Try to get repository info with the new token + const repoInfo = await this._githubService.getRepositoryInfo(); + const config = vscode.workspace.getConfiguration("codeql-scanner"); + const token = config.get("github.token"); + + // Update UI with authentication status + this._view?.webview.postMessage({ + command: "authCompleted", + success: true, + message: "Successfully authenticated with GitHub", + config: { + githubToken: token, + githubOwner: repoInfo.owner, + githubRepo: repoInfo.repo, + } + }); + } catch (repoError) { + // Still authenticated but couldn't get repo info + this.logger.warn("UiProvider", "Authenticated but couldn't get repository info", repoError); + + this._view?.webview.postMessage({ + command: "authCompleted", + success: true, + message: "Successfully authenticated with GitHub, but couldn't retrieve repository information.", + }); + } + + // Reload the configuration to update the UI + this.loadConfiguration(); + } else { + this.logger.logServiceCall("UiProvider", "loginWithGitHub", "failed"); + this._view?.webview.postMessage({ + command: "authCompleted", + success: false, + message: "GitHub authentication failed or was cancelled.", + }); + } + } catch (error) { + this.logger.logServiceCall("UiProvider", "loginWithGitHub", "failed", error); + this._view?.webview.postMessage({ + command: "authCompleted", + success: false, + message: `GitHub authentication failed: ${error instanceof Error ? error.message : String(error)}`, + }); + } + } + private mapGitHubSeverityToLocal(severity?: string): string { if (!severity) return "medium"; @@ -927,6 +1014,44 @@ export class UiProvider implements vscode.WebviewViewProvider { 50% { opacity: 0.7; transform: scale(1.05); } } + /* GitHub Login Button */ + .github-login-btn { + background: linear-gradient(135deg, #2F4858 0%, #333 100%); + color: white; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); + position: relative; + border: 1px solid rgba(255, 255, 255, 0.2); + } + + .github-login-btn.authenticated { + background: linear-gradient(135deg, #28a745 0%, #22863a 100%); + border: 1px solid rgba(40, 167, 69, 0.5); + box-shadow: 0 4px 12px rgba(40, 167, 69, 0.3); + } + + .github-login-btn:hover:not(:disabled) { + background: linear-gradient(135deg, #24292e 0%, #1b1f23 100%); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4); + } + + .github-login-btn.authenticated:hover:not(:disabled) { + background: linear-gradient(135deg, #22863a 0%, #1e7e34 100%); + box-shadow: 0 6px 20px rgba(40, 167, 69, 0.4); + } + + .github-login-btn:disabled { + background: linear-gradient(135deg, #9ca3af 0%, #6b7280 100%); + } + + .github-icon { + font-size: 16px; + transition: all 0.3s ease; + } + + .github-login-btn:hover:not(:disabled) .github-icon { + transform: scale(1.1); + } + /* Fetch Remote Button */ #fetchButton { background: linear-gradient(135deg, #48bb78 0%, #38a169 100%); @@ -1841,6 +1966,12 @@ export class UiProvider implements vscode.WebviewViewProvider {

🚀 Actions

+
+ +