diff --git a/deadlock-plugins/deadlock-extension/resources/js/gettingStartedView.js b/deadlock-plugins/deadlock-extension/resources/js/gettingStartedView.js index 25e68cbb73e0b79b548e9c8b627c67ba503c77b2..d8a04573d23f3fbbc5aa397d8d0ab8d9fb6e3bd5 100644 --- a/deadlock-plugins/deadlock-extension/resources/js/gettingStartedView.js +++ b/deadlock-plugins/deadlock-extension/resources/js/gettingStartedView.js @@ -6,3 +6,9 @@ function launchChooseMissionWorkdirAction() { command: 'launchChooseMissionWorkdirAction', }); } + +function openAuthenticationPageAction() { + vscode.postMessage({ + command: 'openAuthenticationPageAction', + }); +} diff --git a/deadlock-plugins/deadlock-extension/src/core/commandHandler.ts b/deadlock-plugins/deadlock-extension/src/core/commandHandler.ts index 39ae1f9f9e5b4b7fa3230c91a4508ee105f11b7c..8e042408c9f48529d232066e87e16e8811147c41 100644 --- a/deadlock-plugins/deadlock-extension/src/core/commandHandler.ts +++ b/deadlock-plugins/deadlock-extension/src/core/commandHandler.ts @@ -1,16 +1,18 @@ import { commands, Uri, window } from 'vscode'; import { Command } from '../theia/command'; +import Controller from './controller'; import ExtensionStore from './extensionStore'; export class CommandHandler { private extensionStore: ExtensionStore; - constructor() { + constructor(private parent: Controller) { this.extensionStore = ExtensionStore.getInstance(); this.initCommandHandler(); } initCommandHandler() { commands.registerCommand(CHOOSE_MISSION_WORKDIR_COMMAND.cmd, this.chooseMissionWorkdir.bind(this)); + commands.registerCommand(AUTHENTICATE_COMMAND.cmd, this.parent.authenticate.bind(this.parent)); } async chooseMissionWorkdir() { @@ -35,3 +37,4 @@ export class CommandHandler { } export const CHOOSE_MISSION_WORKDIR_COMMAND = new Command('Choose mission workdir', 'deadlock.chooseMissionWorkdir'); +export const AUTHENTICATE_COMMAND = new Command('Authenticate', 'deadlock.authenticate'); diff --git a/deadlock-plugins/deadlock-extension/src/core/controller.ts b/deadlock-plugins/deadlock-extension/src/core/controller.ts index e7a7ee088ab0c7071da97f5d07fcabce329a3475..27dc4631691897fd4b5cb23322f2c5ce5bfc7852 100644 --- a/deadlock-plugins/deadlock-extension/src/core/controller.ts +++ b/deadlock-plugins/deadlock-extension/src/core/controller.ts @@ -1,22 +1,51 @@ -import { link } from 'fs'; -import { url } from 'inspector'; import * as vscode from 'vscode'; import { OPEN_GETTING_STARTED_COMMAND } from '../theia/command'; -import { CHOOSE_MISSION_WORKDIR_COMMAND } from './commandHandler'; +import BriefingView from '../view/briefingView'; +import GettingStartedView from '../view/gettingStartedView'; +import { CHOOSE_MISSION_WORKDIR_COMMAND, CommandHandler } from './commandHandler'; import ExtensionStore from './extensionStore'; import KeycloakOAuth2DeviceFlowConnection from './keycloakOAuth2DeviceFlowConnection'; export default class Controller { - private connection: KeycloakOAuth2DeviceFlowConnection; - - constructor() { + public connection: KeycloakOAuth2DeviceFlowConnection; + private commandHandler: CommandHandler; + private briefingView; + private gettingStartedView: GettingStartedView; + constructor(private context: vscode.ExtensionContext) { + this.briefingView = new BriefingView(); + this.gettingStartedView = new GettingStartedView(context.extensionUri); + this.commandHandler = new CommandHandler(this); this.connection = new KeycloakOAuth2DeviceFlowConnection( 'https://auth.dev.deadlock.io/auth/realms/Deadlock/protocol/openid-connect/auth/device', 'https://auth.dev.deadlock.io/auth/realms/Deadlock/protocol/openid-connect/token', + 'https://auth.dev.deadlock.io/auth/realms/Deadlock/protocol/openid-connect/userinfo', ); - } - openBrowserWithUrl(url: string) { + const that = this; + vscode.window.registerUriHandler({ + handleUri(uri: vscode.Uri) { + const queryParams: URLSearchParams = new URLSearchParams(uri.query); + const action: string | null = queryParams.get('action'); + + switch (action) { + case 'open-challenge': + that.launchMission(queryParams.get('missionId')); + break; + + default: + vscode.window.showInformationMessage('Aucune action trouvée!'); + } + }, + }); + } + async authenticate() { + const tokens = await this.connection.getToken({ openLink: Controller.openBrowserWithUrl }); + const exensionStorage = ExtensionStore.getInstance(); + await exensionStorage.setAccessToken(tokens.accessToken); + await exensionStorage.setRefreshToken(tokens.refreshToken); + this.gettingStartedView.isAlreadyConnected = !!(await exensionStorage.getAccessToken()); + } + public static openBrowserWithUrl(url: string) { vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(url)); } @@ -29,14 +58,16 @@ export default class Controller { await vscode.commands.executeCommand(CHOOSE_MISSION_WORKDIR_COMMAND.cmd); } - const isConnected = (await extensionStore.getAccessToken()) !== undefined; + const hadBeenConnected = (await extensionStore.getAccessToken()) !== undefined; console.log('accesToke: ' + extensionStore.getAccessToken()); - //TODO: Connection - if (!isConnected) { - const { accessToken, refreshToken } = await this.connection.getToken({ openLink: this.openBrowserWithUrl }); - console.log('VOICI LES TOKENS'); - console.log(accessToken, refreshToken); + if (!hadBeenConnected) { + const { accessToken, refreshToken } = await this.connection.getToken({ + openLink: Controller.openBrowserWithUrl, + }); + vscode.window.showInformationMessage('Nouvelle connexion validée'); + } else { + vscode.window.showInformationMessage('Déjà connecté: session récupérée'); } vscode.commands.executeCommand(OPEN_GETTING_STARTED_COMMAND.cmd); diff --git a/deadlock-plugins/deadlock-extension/src/core/extensionStore.ts b/deadlock-plugins/deadlock-extension/src/core/extensionStore.ts index 4caf27caac6572782af73c23cc9e0b2ac3598c1e..678434df6ecd77bfdbc72d8c3c58eabe2f8b7c7e 100644 --- a/deadlock-plugins/deadlock-extension/src/core/extensionStore.ts +++ b/deadlock-plugins/deadlock-extension/src/core/extensionStore.ts @@ -23,11 +23,10 @@ export default class ExtensionStore { } public static createInstance(context: ExtensionContext) { - if (ExtensionStore.instance) { - return ExtensionStore.instance; + if (!ExtensionStore.instance) { + ExtensionStore.instance = new ExtensionStore(context); } - - ExtensionStore.instance = new ExtensionStore(context); + return ExtensionStore.instance; } getMissionWorkdir(): string | undefined { diff --git a/deadlock-plugins/deadlock-extension/src/extension.ts b/deadlock-plugins/deadlock-extension/src/extension.ts index cfc72593482ca94f3c556dcfd98cca2780d89be6..13507f0ba1bc885ad11b8397476fa261d9090982 100644 --- a/deadlock-plugins/deadlock-extension/src/extension.ts +++ b/deadlock-plugins/deadlock-extension/src/extension.ts @@ -1,49 +1,19 @@ import * as vscode from 'vscode'; -import { CommandHandler } from './core/commandHandler'; import { SERVICES_PATHS_PATH } from './core/config'; import Controller from './core/controller'; import ExtensionStore from './core/extensionStore'; -import { default as KeycloakOAuth2DeviceFlowConnectionTest } from './core/keycloakOAuth2DeviceFlowConnection.test'; import MetadataProvider from './core/metadataProvider'; import { error } from './recorder/utils'; import { DepNodeProvider } from './theia/deadlockPanel'; import UserConfigTheia from './theia/userConfigTheia'; -import BriefingView from './view/briefingView'; -import GettingStartedView from './view/gettingStartedView'; -export function initViews(extensionUri: vscode.Uri) { - new GettingStartedView(extensionUri); - new BriefingView(); -} - -export function initCommandHandlers() { - new CommandHandler(); -} export const userConfig = new UserConfigTheia(); export async function activate(context: vscode.ExtensionContext) { vscode.window.showInformationMessage('Bienvenue sur Deadlock!'); ExtensionStore.createInstance(context); - const controller = new Controller(); - - vscode.window.registerUriHandler({ - handleUri(uri: vscode.Uri) { - const queryParams: URLSearchParams = new URLSearchParams(uri.query); - const action: string | null = queryParams.get('action'); - - switch (action) { - case 'open-challenge': - controller.launchMission(queryParams.get('missionId')); - break; - - default: - vscode.window.showInformationMessage('Aucune action trouvée!'); - } - }, - }); - initViews(context.extensionUri); - initCommandHandlers(); + const controller = new Controller(context); // @ts-ignore const deadlockPanelProvider = new DepNodeProvider(vscode.workspace.rootPath); diff --git a/deadlock-plugins/deadlock-extension/src/view/gettingStartedView.ts b/deadlock-plugins/deadlock-extension/src/view/gettingStartedView.ts index 113a197bba0dccba35227fdc9fe49b22bc7fab87..1328b0440e558dee535754d5a3e57aa96c4bc385 100644 --- a/deadlock-plugins/deadlock-extension/src/view/gettingStartedView.ts +++ b/deadlock-plugins/deadlock-extension/src/view/gettingStartedView.ts @@ -1,5 +1,5 @@ import * as vscode from 'vscode'; -import { CHOOSE_MISSION_WORKDIR_COMMAND } from '../core/commandHandler'; +import { AUTHENTICATE_COMMAND, CHOOSE_MISSION_WORKDIR_COMMAND } from '../core/commandHandler'; import ExtensionStore from '../core/extensionStore'; import { log } from '../recorder/utils'; import { OPEN_GETTING_STARTED_COMMAND } from '../theia/command'; @@ -10,11 +10,20 @@ export const GETTING_STARTED_ID = 'gettingStarted'; export default class GettingStartedView extends WebviewBase { private extensionUri: vscode.Uri; private extensionStore: ExtensionStore; + private _isAlreadyConnected: boolean; constructor(extensionUri: vscode.Uri) { super(GETTING_STARTED_ID, 'GettingStarted', OPEN_GETTING_STARTED_COMMAND); this.extensionUri = extensionUri; this.extensionStore = ExtensionStore.getInstance(); + this._isAlreadyConnected = false; + } + + set isAlreadyConnected(newVal: boolean) { + if (this._isAlreadyConnected !== newVal) { + this._isAlreadyConnected = newVal; + this.reload(); + } } render(): string { @@ -30,7 +39,6 @@ export default class GettingStartedView extends WebviewBase { renderHtmlBody() { const hadMissionWorkdir = this.extensionStore.getMissionWorkdir() !== undefined; - const isAlreadyConnected = false; return ` <h1>Getting Started</h1> @@ -40,7 +48,8 @@ export default class GettingStartedView extends WebviewBase { 'Connexion à Deadlock', "Tu as besoin d'être connecté à Deadlock pour continuer.", { name: 'Se connecter', onClickFunctionName: 'openAuthenticationPageAction' }, - isAlreadyConnected, + this._isAlreadyConnected, + this._isAlreadyConnected, )} ${this.renderCardHtml( 'Dossier contenant tes exercices', @@ -62,6 +71,7 @@ export default class GettingStartedView extends WebviewBase { description: string, button: { name: string; onClickFunctionName: string }, isChecked: boolean, + isDisabled?: boolean, callbackArgs?: string, ) { return ` @@ -74,7 +84,9 @@ export default class GettingStartedView extends WebviewBase { <div class="card-description"> ${description} </div> - <vscode-button onclick="${button.onClickFunctionName}(${callbackArgs})">${button.name}</vscode-button> + <vscode-button ${isDisabled ? 'disabled' : ''} onclick="${button.onClickFunctionName}(${callbackArgs})">${ + button.name + }</vscode-button> </div> </div> @@ -111,6 +123,9 @@ export default class GettingStartedView extends WebviewBase { case 'launchChooseMissionWorkdirAction': vscode.commands.executeCommand(CHOOSE_MISSION_WORKDIR_COMMAND.cmd).then(() => this.reload()); return; + case 'openAuthenticationPageAction': + vscode.commands.executeCommand(AUTHENTICATE_COMMAND.cmd); + return; } }