diff --git a/deadlock-plugins/deadlock-extension/src/core/config.ts b/deadlock-plugins/deadlock-extension/src/core/config.ts index 9dbf60baf06d19973a8a8abf05f0d17c45b8cec0..9a002fc30a0a235ede4e04ee397011cf5374b16c 100644 --- a/deadlock-plugins/deadlock-extension/src/core/config.ts +++ b/deadlock-plugins/deadlock-extension/src/core/config.ts @@ -8,8 +8,7 @@ const onContainer = isDocker(); const deadlockExtensionPath = path.join(homeDir, 'deadlock-extension'); -const deadlockConfigPath = path.join(homeDir, '.deadlock'); -export const userSshKeyFolderPath = path.join(deadlockConfigPath, '.ssh'); +export const deadlockConfigPath = path.join(homeDir, '.deadlock'); export const PROJECT_SRC_PATH = onContainer ? '/project' : path.join(homeDir, 'deadlock-extension', '/project'); diff --git a/deadlock-plugins/deadlock-extension/src/core/controller.ts b/deadlock-plugins/deadlock-extension/src/core/controller.ts index 145974603be899716d75a8f23573a9438a25bd52..13c2961dd8545a63eaab41fbe5baf2e08f423647 100644 --- a/deadlock-plugins/deadlock-extension/src/core/controller.ts +++ b/deadlock-plugins/deadlock-extension/src/core/controller.ts @@ -92,10 +92,10 @@ export default class Controller { this.quickSetupView.isAlreadyConnected = false; } - public async createSshKeyPairIfNotExist() { + public async createSshKeyPairIfNotExist(userId: string) { if (isSshKeyPairExist()) return; const { publicKey, privateKey } = await this.apiService.getUserSshKey(); - await createSshKeyFiles(publicKey, privateKey); + await createSshKeyFiles(publicKey, privateKey, userId); } public async authenticate() { @@ -103,8 +103,10 @@ export default class Controller { const tokens = await this.connection.getToken({ openLink: Controller.openBrowserWithUrl }); await this.extensionStore.setAccessToken(tokens.accessToken); await this.extensionStore.setRefreshToken(tokens.refreshToken); - await this.createSshKeyPairIfNotExist(); + const user = await this.apiService.getUser(); + await this.createSshKeyPairIfNotExist(user.id); this.quickSetupView.isAlreadyConnected = true; + return user; } public static openBrowserWithUrl(url: string) { @@ -120,15 +122,18 @@ export default class Controller { const hadBeenConnected = (await this.extensionStore.getAccessToken()) !== undefined; + let user: User; + if (!hadBeenConnected) { - await this.authenticate(); + user = await this.authenticate(); window.showInformationMessage('Connexion validée'); + } else { + user = await this.apiService.getUser(); } const mission = new Mission(missionId, missionVersion); const missionsWorkdir = this.extensionStore.getMissionWorkdir() ?? ''; - const user: User = await this.apiService.getUser(); const giteaPublicProperties: GiteaPublicProperties = await this.apiService.getGiteaPublicProperties(); const missionDevcontainer = new MissionDevContainer(missionsWorkdir, user, mission, giteaPublicProperties); diff --git a/deadlock-plugins/deadlock-extension/src/core/extensionStore.ts b/deadlock-plugins/deadlock-extension/src/core/extensionStore.ts index 9759b5e1559f2e1252a1c3a5740dc9beb47e99a9..269dbf9599ecb991b452d39b7b73201d9fb90ebd 100644 --- a/deadlock-plugins/deadlock-extension/src/core/extensionStore.ts +++ b/deadlock-plugins/deadlock-extension/src/core/extensionStore.ts @@ -50,6 +50,10 @@ export default class ExtensionStore { return this.readSecret(StoreKey.RefreshTokenKey); } + public getSshFolderPath(): Thenable<string | undefined> { + return this.readSecret(StoreKey.SshFolderKey); + } + public setAccessToken(accessToken: string): Thenable<void> { if (!accessToken) { log('Attempt to store undefined access token'); @@ -66,6 +70,14 @@ export default class ExtensionStore { return this.storeSecret(StoreKey.RefreshTokenKey, refreshToken); } + public setSshFolderPath(path: string): Thenable<void> { + if (!path) { + log('Attempt to store undefined path'); + return Promise.resolve(); + } + return this.storeSecret(StoreKey.SshFolderKey, path); + } + private storeSecret(key: StoreKey, value: string): Thenable<void> { return this.secretStorage.store(key, value); } @@ -77,6 +89,7 @@ export default class ExtensionStore { enum StoreKey { MissionWorkdirKey = 'mission-workdir-key', + SshFolderKey = 'ssh-folder-key', AccessTokenKey = 'access-token-key', RefreshTokenKey = 'refresh-token-key', } diff --git a/deadlock-plugins/deadlock-extension/src/core/mission/missionDevContainer.ts b/deadlock-plugins/deadlock-extension/src/core/mission/missionDevContainer.ts index e40df49c8b2c01559bbb84d06d5ef0bc5689aebd..2045c4ad4ac44a35302c83f4f621f081cfed2063 100644 --- a/deadlock-plugins/deadlock-extension/src/core/mission/missionDevContainer.ts +++ b/deadlock-plugins/deadlock-extension/src/core/mission/missionDevContainer.ts @@ -1,4 +1,4 @@ -import { userSshKeyFolderPath } from '../config'; +import { deadlockConfigPath } from './config'; import { Base, DockerfileSpecific, LifecycleScripts, VSCodespecific } from './devContainer'; import { mkdir, writeFile } from 'fs/promises'; import { Mission } from './mission'; @@ -90,7 +90,7 @@ export class MissionDevContainer { const image = `${this.dockerImageUrl}/${this.mission.id}:${this.mission.version}`; this.mounts.push( - `source=${userSshKeyFolderPath},target=/tmp/.ssh,type=bind,consistency=cached,readonly`, + `source=${join(deadlockConfigPath, this.user.id, '.ssh')},target=/tmp/.ssh,type=bind,consistency=cached,readonly`, `source=${this.dirs.config},target=/home/config/,type=bind,consistency=cached,readonly`, 'source=/etc/hosts,target=/etc/hosts,type=bind,consistency=cached,readonly', ); diff --git a/deadlock-plugins/deadlock-extension/src/core/sshKeyManager.ts b/deadlock-plugins/deadlock-extension/src/core/sshKeyManager.ts index c3fdbb764f09ffa71ca1db5313e6cd09becb886a..f263067dc275c691d45b08ac4c02ad557218f057 100644 --- a/deadlock-plugins/deadlock-extension/src/core/sshKeyManager.ts +++ b/deadlock-plugins/deadlock-extension/src/core/sshKeyManager.ts @@ -1,30 +1,35 @@ import { existsSync, promises } from 'fs'; -import { userSshKeyFolderPath } from './config'; +import { deadlockConfigPath } from './config'; +import { join } from 'path'; - export function isSshKeyPairExist(): boolean { - return isPrivateKeyExist() && isPublicKeyExist(); - } +let currentUserSshKeyFolderPath: string; - function isPublicKeyExist(): boolean { - return existsSync(`${userSshKeyFolderPath}/id_rsa.pub`); - } +export function isSshKeyPairExist(): boolean { + return isPrivateKeyExist() && isPublicKeyExist(); +} - function isPrivateKeyExist(): boolean { - return existsSync(`${userSshKeyFolderPath}/id_rsa`); - } +function isPublicKeyExist(): boolean { + return existsSync(`${currentUserSshKeyFolderPath}/id_rsa.pub`); +} - export async function createSshKeyFiles(publicKey: string, privateKey: string) { - await createSshKeyFolderIfNotExist(userSshKeyFolderPath); - await promises.writeFile(`${userSshKeyFolderPath}/id_rsa.pub`, publicKey); +function isPrivateKeyExist(): boolean { + return existsSync(`${currentUserSshKeyFolderPath}/id_rsa`); +} - await promises.writeFile(`${userSshKeyFolderPath}/id_rsa`, privateKey, { mode: 0o600 }); - } - async function createSshKeyFolderIfNotExist(sshKeyFolderPath) { - if (!isSshKeyFolderExist(sshKeyFolderPath)) { - await promises.mkdir(sshKeyFolderPath, { recursive: true }); - } - } +export async function createSshKeyFiles(publicKey: string, privateKey: string, userId: string) { + currentUserSshKeyFolderPath = join(deadlockConfigPath, userId, '.ssh'); + await createSshKeyFolderIfNotExist(currentUserSshKeyFolderPath); + await promises.writeFile(`${currentUserSshKeyFolderPath}/id_rsa.pub`, publicKey); + + await promises.writeFile(`${currentUserSshKeyFolderPath}/id_rsa`, privateKey, { mode: 0o600 }); +} - export function isSshKeyFolderExist(sshKeyFolderPath: string) { - return existsSync(sshKeyFolderPath); +async function createSshKeyFolderIfNotExist(sshKeyFolderPath) { + if (!isSshKeyFolderExist(sshKeyFolderPath)) { + await promises.mkdir(sshKeyFolderPath, { recursive: true }); } +} + +function isSshKeyFolderExist(sshKeyFolderPath: string) { + return existsSync(sshKeyFolderPath); +}