diff --git a/deadlock-plugins/deadlock-extension/package-lock.json b/deadlock-plugins/deadlock-extension/package-lock.json
index fc5c9c6c2f51a9c1d827fe8bbf31a7445ac3f446..53a947b0a3226322d98da1bda1d99b69a478feea 100644
--- a/deadlock-plugins/deadlock-extension/package-lock.json
+++ b/deadlock-plugins/deadlock-extension/package-lock.json
@@ -8,6 +8,7 @@
       "name": "deadlock-coding",
       "version": "0.1.10",
       "dependencies": {
+        "@types/tar": "^6.1.1",
         "@types/yaml": "^1.9.7",
         "@vscode/webview-ui-toolkit": "^1.0.0",
         "async": "^3.2.2",
@@ -16,6 +17,7 @@
         "marked": "^4.0.6",
         "node-fetch": "^2.6.7",
         "simple-git": "^3.7.0",
+        "tar": "^6.1.11",
         "yaml": "^2.1.1"
       },
       "devDependencies": {
@@ -1538,11 +1540,18 @@
       "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
       "dev": true
     },
+    "node_modules/@types/minipass": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/@types/minipass/-/minipass-3.1.2.tgz",
+      "integrity": "sha512-foLGjgrJkUjLG/o2t2ymlZGEoBNBa/TfoUZ7oCTkOjP1T43UGBJspovJou/l3ZuHvye2ewR5cZNtp2zyWgILMA==",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/node": {
       "version": "14.18.21",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.21.tgz",
-      "integrity": "sha512-x5W9s+8P4XteaxT/jKF0PSb7XEvo5VmqEWgsMlyeY4ZlLK8I6aH6g5TPPyDlLAep+GYf4kefb7HFyc7PAO3m+Q==",
-      "dev": true
+      "integrity": "sha512-x5W9s+8P4XteaxT/jKF0PSb7XEvo5VmqEWgsMlyeY4ZlLK8I6aH6g5TPPyDlLAep+GYf4kefb7HFyc7PAO3m+Q=="
     },
     "node_modules/@types/node-fetch": {
       "version": "2.6.1",
@@ -1621,6 +1630,15 @@
       "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
       "dev": true
     },
+    "node_modules/@types/tar": {
+      "version": "6.1.1",
+      "resolved": "https://registry.npmjs.org/@types/tar/-/tar-6.1.1.tgz",
+      "integrity": "sha512-8mto3YZfVpqB1CHMaYz1TUYIQfZFbh/QbEq5Hsn6D0ilCfqRVCdalmc89B7vi3jhl9UYIk+dWDABShNfOkv5HA==",
+      "dependencies": {
+        "@types/minipass": "*",
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/vscode": {
       "version": "1.67.0",
       "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.67.0.tgz",
@@ -4408,6 +4426,17 @@
       "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
       "dev": true
     },
+    "node_modules/fs-minipass": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+      "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+      "dependencies": {
+        "minipass": "^3.0.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
     "node_modules/fs-monkey": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz",
@@ -6714,6 +6743,40 @@
       "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
       "dev": true
     },
+    "node_modules/minipass": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.3.tgz",
+      "integrity": "sha512-N0BOsdFAlNRfmwMhjAsLVWOk7Ljmeb39iqFlsV1At+jqRhSUP9yeof8FyJu4imaJiSUp8vQebWD/guZwGQC8iA==",
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/minizlib": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+      "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+      "dependencies": {
+        "minipass": "^3.0.0",
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/mkdirp": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+      "bin": {
+        "mkdirp": "bin/cmd.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/mkdirp-classic": {
       "version": "0.5.3",
       "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
@@ -8569,6 +8632,22 @@
         "node": ">=6"
       }
     },
+    "node_modules/tar": {
+      "version": "6.1.11",
+      "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
+      "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
+      "dependencies": {
+        "chownr": "^2.0.0",
+        "fs-minipass": "^2.0.0",
+        "minipass": "^3.0.0",
+        "minizlib": "^2.1.1",
+        "mkdirp": "^1.0.3",
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
     "node_modules/tar-fs": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
@@ -8611,6 +8690,14 @@
         "node": ">= 6"
       }
     },
+    "node_modules/tar/node_modules/chownr": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+      "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/terminal-link": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
@@ -9720,8 +9807,7 @@
     "node_modules/yallist": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
-      "dev": true
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
     },
     "node_modules/yaml": {
       "version": "2.1.1",
@@ -11034,11 +11120,18 @@
       "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
       "dev": true
     },
+    "@types/minipass": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/@types/minipass/-/minipass-3.1.2.tgz",
+      "integrity": "sha512-foLGjgrJkUjLG/o2t2ymlZGEoBNBa/TfoUZ7oCTkOjP1T43UGBJspovJou/l3ZuHvye2ewR5cZNtp2zyWgILMA==",
+      "requires": {
+        "@types/node": "*"
+      }
+    },
     "@types/node": {
       "version": "14.18.21",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.21.tgz",
-      "integrity": "sha512-x5W9s+8P4XteaxT/jKF0PSb7XEvo5VmqEWgsMlyeY4ZlLK8I6aH6g5TPPyDlLAep+GYf4kefb7HFyc7PAO3m+Q==",
-      "dev": true
+      "integrity": "sha512-x5W9s+8P4XteaxT/jKF0PSb7XEvo5VmqEWgsMlyeY4ZlLK8I6aH6g5TPPyDlLAep+GYf4kefb7HFyc7PAO3m+Q=="
     },
     "@types/node-fetch": {
       "version": "2.6.1",
@@ -11117,6 +11210,15 @@
       "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
       "dev": true
     },
+    "@types/tar": {
+      "version": "6.1.1",
+      "resolved": "https://registry.npmjs.org/@types/tar/-/tar-6.1.1.tgz",
+      "integrity": "sha512-8mto3YZfVpqB1CHMaYz1TUYIQfZFbh/QbEq5Hsn6D0ilCfqRVCdalmc89B7vi3jhl9UYIk+dWDABShNfOkv5HA==",
+      "requires": {
+        "@types/minipass": "*",
+        "@types/node": "*"
+      }
+    },
     "@types/vscode": {
       "version": "1.67.0",
       "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.67.0.tgz",
@@ -13269,6 +13371,14 @@
       "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
       "dev": true
     },
+    "fs-minipass": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+      "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
     "fs-monkey": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz",
@@ -15009,6 +15119,28 @@
       "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
       "dev": true
     },
+    "minipass": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.3.tgz",
+      "integrity": "sha512-N0BOsdFAlNRfmwMhjAsLVWOk7Ljmeb39iqFlsV1At+jqRhSUP9yeof8FyJu4imaJiSUp8vQebWD/guZwGQC8iA==",
+      "requires": {
+        "yallist": "^4.0.0"
+      }
+    },
+    "minizlib": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+      "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+      "requires": {
+        "minipass": "^3.0.0",
+        "yallist": "^4.0.0"
+      }
+    },
+    "mkdirp": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
+    },
     "mkdirp-classic": {
       "version": "0.5.3",
       "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
@@ -16444,6 +16576,26 @@
       "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
       "dev": true
     },
+    "tar": {
+      "version": "6.1.11",
+      "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
+      "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
+      "requires": {
+        "chownr": "^2.0.0",
+        "fs-minipass": "^2.0.0",
+        "minipass": "^3.0.0",
+        "minizlib": "^2.1.1",
+        "mkdirp": "^1.0.3",
+        "yallist": "^4.0.0"
+      },
+      "dependencies": {
+        "chownr": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+          "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
+        }
+      }
+    },
     "tar-fs": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
@@ -17263,8 +17415,7 @@
     "yallist": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
-      "dev": true
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
     },
     "yaml": {
       "version": "2.1.1",
diff --git a/deadlock-plugins/deadlock-extension/package.json b/deadlock-plugins/deadlock-extension/package.json
index 5cacb47740180ba5b093b73bc8699d9a4aa71598..a613b0827df752b672566f9b0e0a368950ab0019 100644
--- a/deadlock-plugins/deadlock-extension/package.json
+++ b/deadlock-plugins/deadlock-extension/package.json
@@ -98,6 +98,7 @@
     "postversion": "git add package*.json && auto-changelog -p && git add CHANGELOG.md && git commit -m \"build: $npm_package_version\""
   },
   "dependencies": {
+    "@types/tar": "^6.1.1",
     "@types/yaml": "^1.9.7",
     "@vscode/webview-ui-toolkit": "^1.0.0",
     "async": "^3.2.2",
@@ -106,6 +107,7 @@
     "marked": "^4.0.6",
     "node-fetch": "^2.6.7",
     "simple-git": "^3.7.0",
+    "tar": "^6.1.11",
     "yaml": "^2.1.1"
   },
   "devDependencies": {
diff --git a/deadlock-plugins/deadlock-extension/src/core/api.service.ts b/deadlock-plugins/deadlock-extension/src/core/api.service.ts
index d4e5330788ef9949fa85b535c4c2828df8933a15..3e1aa50c78a641ceb0e02c9f5ac75ff34929fb62 100644
--- a/deadlock-plugins/deadlock-extension/src/core/api.service.ts
+++ b/deadlock-plugins/deadlock-extension/src/core/api.service.ts
@@ -6,8 +6,8 @@ import { extensionError as error } from '../recorder/utils/log';
 import Controller from './controller';
 import ExtensionStore from './extensionStore';
 import KeycloakOAuth2DeviceFlowConnection from './keycloakOAuth2DeviceFlowConnection';
-import { MissionUser } from './mission/models/missionUser';
-import { User } from './mission/models/userChallenge';
+import { MissionUser } from './mission/model/missionUser';
+import { User } from './mission/model/userChallenge';
 
 export default class ApiService {
   private axiosInstance: AxiosInstance;
@@ -130,6 +130,10 @@ export default class ApiService {
     return this.axiosInstance.get<User>(`users/${userId}`).then((res) => res.data);
   }
 
+  async getSolution(mission: string): Promise<NodeJS.ArrayBufferView> {
+    return this.axiosInstance.get<NodeJS.ArrayBufferView>(`missions/${mission}/solution`).then((res) => res.data);
+  }
+
   async grantAccessToRepository(userId: string, missionId: string): Promise<number> {
     return this.axiosInstance
       .post<MissionUser>(`users/${userId}/missions/${missionId}/repository/collaborator`)
diff --git a/deadlock-plugins/deadlock-extension/src/core/controller.ts b/deadlock-plugins/deadlock-extension/src/core/controller.ts
index 087121c433ee9412d8254a669136e7548de7dd32..5fc0a303fec3b680370761eb36a3fb48c8a37ce2 100644
--- a/deadlock-plugins/deadlock-extension/src/core/controller.ts
+++ b/deadlock-plugins/deadlock-extension/src/core/controller.ts
@@ -7,13 +7,21 @@ import KeycloakOAuth2DeviceFlowConnection from './keycloakOAuth2DeviceFlowConnec
 import ApiService from './api.service';
 import { GiteaPublicProperties } from '../model/giteaPublicProperties.model';
 import { MissionDevContainer } from './mission/missionDevContainer';
-import { extensionLog as log } from '../recorder/utils/log';
+import { extensionError, extensionLog as log } from '../recorder/utils/log';
 import { commands, ExtensionContext, Uri, window } from 'vscode';
 import { createSshKeyFiles } from './sshKeyManager';
 import { emptyDirectories, removeFilesOrDirectories } from '../recorder/utils/workdir';
 import { missionWorkdir, userSshKeyFolderPath } from './config';
 import { hasStatusNumber } from './utils/typeguards';
-import { User } from './mission/models/userChallenge';
+import { User } from './mission/model/userChallenge';
+import { existsSync, mkdirSync, writeFileSync } from 'fs';
+import { extract } from 'tar';
+import { parse } from 'yaml';
+import isDocker from './utils/isdocker';
+import * as fs from 'fs';
+import { getReviewedStudentWorkdirPath } from './utils/mission.utils';
+import { join } from 'path';
+import Mission from '../model/mission';
 
 export default class Controller {
   private static instance: Controller;
@@ -21,11 +29,19 @@ export default class Controller {
   private commandHandler: CommandHandler;
   private briefingView: BriefingView;
   private quickSetupView: QuickSetupView;
-  private extensionStore: ExtensionStore;
   private _apiService: ApiService;
+  private _extensionStore: ExtensionStore;
+
+  public get extensionStore() {
+    return this._extensionStore;
+  }
+
+  public get apiService() {
+    return this._apiService;
+  }
 
   private constructor(context: ExtensionContext) {
-    this.extensionStore = ExtensionStore.getInstance(context);
+    this._extensionStore = ExtensionStore.getInstance(context);
     this.briefingView = new BriefingView();
     this.quickSetupView = new QuickSetupView(context.extensionUri);
     this.commandHandler = new CommandHandler(this);
@@ -35,20 +51,53 @@ export default class Controller {
       KEYCLOAK_USER_INFO_URL,
     );
 
-    this._apiService = new ApiService(this.connection, this.extensionStore, this);
+    this._apiService = new ApiService(this.connection, this._extensionStore, this);
 
     this.init();
   }
 
-  public static getInstance(context: ExtensionContext): Controller {
+  public static getInstance(context?: ExtensionContext): Controller {
     if (!Controller.instance) {
+      if (context === undefined) {
+        throw new Error('Controller needs a context when instantiated');
+      }
       Controller.instance = new Controller(context);
     }
     return Controller.instance;
   }
 
-  public get apiService(): ApiService {
-    return this._apiService;
+  getChallenge(missionId: string): Mission | undefined {
+    if (!isDocker()) {
+      return parse(`${missionWorkdir}/${missionId}/challenge.yaml`);
+    }
+  }
+
+  public async getSolution(missionId: string, reviewedId: string) {
+    try {
+      const solution = await this._apiService.getSolution(missionId);
+      const solutionFolder = join(getReviewedStudentWorkdirPath(reviewedId), missionId, '.solution');
+      const tarName = 'solution.tar.gz';
+      const tarPath = join(solutionFolder, tarName);
+
+      if (existsSync(solutionFolder)) {
+        fs.rmSync(solutionFolder, { recursive: true });
+      }
+
+      mkdirSync(solutionFolder);
+
+      writeFileSync(tarPath, solution);
+      extract({ sync: true, file: `${solutionFolder}/${tarName}`, cwd: solutionFolder });
+      await removeFilesOrDirectories(`${solutionFolder}/${tarName}`);
+      // list files in the folder
+      fs.readdirSync(solutionFolder).forEach((file) => {
+        const tmpSolutionPath = join(solutionFolder, file);
+        fs.readdirSync(tmpSolutionPath).map((f) => fs.renameSync(join(tmpSolutionPath, f), join(solutionFolder, f)));
+        fs.rmSync(tmpSolutionPath, { recursive: true });
+      });
+    } catch (e) {
+      window.showErrorMessage(`Une erreur est survenue lors de la récupération de la solution`);
+      extensionError(e);
+    }
   }
 
   private async init() {
@@ -79,7 +128,7 @@ export default class Controller {
       },
     });
 
-    this.quickSetupView.isAlreadyConnected = (await this.extensionStore.getAccessToken()) !== undefined;
+    this.quickSetupView.isAlreadyConnected = (await this._extensionStore.getAccessToken()) !== undefined;
   }
 
   public async disconnect() {
@@ -90,15 +139,15 @@ export default class Controller {
   }
 
   public async createSshKeyPair() {
-    const { publicKey, privateKey } = await this.apiService.getUserSshKey();
+    const { publicKey, privateKey } = await this._apiService.getUserSshKey();
     await createSshKeyFiles(publicKey, privateKey);
   }
 
   public async authenticate() {
     await this.connection.registerDevice();
     const tokens = await this.connection.getToken({ openLink: Controller.openBrowserWithUrl });
-    await this.extensionStore.setAccessToken(tokens.accessToken);
-    await this.extensionStore.setRefreshToken(tokens.refreshToken);
+    await this._extensionStore.setAccessToken(tokens.accessToken);
+    await this._extensionStore.setRefreshToken(tokens.refreshToken);
     await this.createSshKeyPair();
     this.quickSetupView.isAlreadyConnected = true;
   }
@@ -110,7 +159,7 @@ export default class Controller {
   public async launchMission(missionId: string, missionVersion: string, userId?: string) {
     window.showInformationMessage(`vous lancez la mission ${missionId}`);
 
-    const hadBeenConnected = (await this.extensionStore.getAccessToken()) !== undefined;
+    const hadBeenConnected = (await this._extensionStore.getAccessToken()) !== undefined;
 
     if (!hadBeenConnected) {
       await this.authenticate();
@@ -119,11 +168,11 @@ export default class Controller {
 
     const currentUser = await this.apiService.getCurrentUser();
 
-    const user: User = userId ? await this.apiService.getUser(userId) : currentUser;
+    const user: User = userId ? await this._apiService.getUser(userId) : currentUser;
 
     if (!!userId && userId !== currentUser.id) {
       try {
-        await this.apiService.grantAccessToRepository(user.id, missionId);
+        await this._apiService.grantAccessToRepository(user.id, missionId);
       } catch (e) {
         if (hasStatusNumber(e)) {
           if (e.status === 403) {
@@ -134,9 +183,15 @@ export default class Controller {
           throw e;
         }
       }
+      try {
+        await Controller.getInstance().getSolution(missionId, user.id);
+      } catch (e) {
+        window.showErrorMessage(`Une erreur est survenue lors de la récupération de la solution`);
+        extensionError(e);
+      }
     }
 
-    const giteaPublicProperties: GiteaPublicProperties = await this.apiService.getGiteaPublicProperties();
+    const giteaPublicProperties: GiteaPublicProperties = await this._apiService.getGiteaPublicProperties();
 
     const missionDevcontainer = new MissionDevContainer(
       user,
diff --git a/deadlock-plugins/deadlock-extension/src/core/mission/missionDevContainer.ts b/deadlock-plugins/deadlock-extension/src/core/mission/missionDevContainer.ts
index ddd9555cf09d61b23c6958aed83640df7287de16..4d155c96fe87454f7a8a8d1fbb50cf01ddfe6e34 100644
--- a/deadlock-plugins/deadlock-extension/src/core/mission/missionDevContainer.ts
+++ b/deadlock-plugins/deadlock-extension/src/core/mission/missionDevContainer.ts
@@ -1,14 +1,15 @@
 import { missionWorkdir, userSshKeyFolderPath } from '../config';
-import { Base, DockerfileSpecific, LifecycleScripts, VSCodespecific } from './models/devContainer';
+import { Base, DockerfileSpecific, LifecycleScripts, VSCodespecific } from './model/devContainer';
 import { mkdir, writeFile } from 'fs/promises';
 import { GiteaPublicProperties } from '../../model/giteaPublicProperties.model';
-import { commands, Uri } from 'vscode';
+import { commands, Uri, window } from 'vscode';
 import { existsSync, copyFileSync } from 'fs';
 import { join } from 'path';
 
 import assert = require('assert');
-import UserChallenge, { User } from './models/userChallenge';
+import UserChallenge, { User } from './model/userChallenge';
 import { REGISTRY_MISSION_URL } from '../../config';
+import { getReviewedStudentWorkdirPath } from '../utils/mission.utils';
 
 const remoteUserHomeDir = '/home/deadlock';
 const remoteMissionDir = `${remoteUserHomeDir}/mission/`;
@@ -27,7 +28,13 @@ export class MissionDevContainer {
   private readonly mounts: string[] = [];
   private readonly extentionPath: string;
 
-  private readonly dirs: { missionWorkdir: string; config: string; devcontainer: string; mounted: string };
+  private readonly dirs: {
+    missionWorkdir: string;
+    config: string;
+    devcontainer: string;
+    mounted: string;
+    solution: string;
+  };
 
   constructor(
     private readonly user: User,
@@ -36,15 +43,18 @@ export class MissionDevContainer {
     private readonly missionVersion: string,
     private readonly giteaProperties: GiteaPublicProperties,
   ) {
-    let prefix = missionWorkdir;
+    let prefix: string;
     if (this.isReviewingStudent()) {
-      prefix += `/students/${this.user.details.lastName}_${this.user.details.firstName}_${this.user.id}`;
+      prefix = getReviewedStudentWorkdirPath(this.user.id);
+    } else {
+      prefix = `${missionWorkdir}`;
     }
     this.dirs = {
       missionWorkdir: `${prefix}/${this.missionId}`,
       config: `${prefix}/${this.missionId}/.config`,
       devcontainer: `${prefix}/${this.missionId}/.devcontainer`,
       mounted: `${prefix}/${this.missionId}/mounted`,
+      solution: `${prefix}/${this.missionId}/.solution`,
     };
     if (process.env.DL_MOUNT_EXTENSION === 'true') {
       this.extentionPath = '/injected-extension/extension.vsix';
@@ -66,9 +76,14 @@ export class MissionDevContainer {
       throw new Error(`${MissionDevContainer.constructor.name} Already initialized`);
     }
     this.isInit = true;
-    await this.createDirectories(...Object.values(this.dirs));
-    await this.createDevContainerFile();
-    await this.createUserChallengeJsonFile();
+    try {
+      await this.createDirectories(...Object.values(this.dirs));
+      await this.createDevContainerFile();
+      await this.createUserChallengeJsonFile();
+    } catch (e) {
+      console.error(e);
+      window.showErrorMessage(`Une erreur est survenue lors de la création de la mission ${this.missionId}`);
+    }
   }
 
   private isReviewingStudent() {
@@ -111,7 +126,8 @@ export class MissionDevContainer {
     }
   }
 
-  private setupMounts(): void {
+  private async setupMounts() {
+    this.mounts.splice(0, this.mounts.length);
     this.mounts.push(
       `source=${userSshKeyFolderPath},target=/tmp/.ssh,type=bind,consistency=cached,readonly`,
       `source=${this.dirs.config},target=/home/config/,type=bind,consistency=cached,readonly`,
@@ -121,10 +137,15 @@ export class MissionDevContainer {
       this.mounts.push(`source=${process.env.EXTENSION_PATH},target=${this.extentionPath},type=bind`);
     }
     this.addInMountRCs(this.dirs.missionWorkdir, '.bashrc', '.zshrc');
+    if (this.isReviewingStudent()) {
+      this.mounts.push(`source=${this.dirs.solution},target=${remoteMissionDir}/solution,type=bind`);
+    }
   }
 
-  private createDevContainerFile(options?: Partial<DockerfileSpecific & Base & VSCodespecific & LifecycleScripts>) {
-    this.setupMounts();
+  private async createDevContainerFile(
+    options?: Partial<DockerfileSpecific & Base & VSCodespecific & LifecycleScripts>,
+  ) {
+    await this.setupMounts();
 
     return writeFile(
       `${this.dirs.devcontainer}/devcontainer.json`,
diff --git a/deadlock-plugins/deadlock-extension/src/core/mission/models/devContainer.ts b/deadlock-plugins/deadlock-extension/src/core/mission/model/devContainer.ts
similarity index 100%
rename from deadlock-plugins/deadlock-extension/src/core/mission/models/devContainer.ts
rename to deadlock-plugins/deadlock-extension/src/core/mission/model/devContainer.ts
diff --git a/deadlock-plugins/deadlock-extension/src/core/mission/models/missionUser.ts b/deadlock-plugins/deadlock-extension/src/core/mission/model/missionUser.ts
similarity index 100%
rename from deadlock-plugins/deadlock-extension/src/core/mission/models/missionUser.ts
rename to deadlock-plugins/deadlock-extension/src/core/mission/model/missionUser.ts
diff --git a/deadlock-plugins/deadlock-extension/src/core/mission/models/userChallenge.ts b/deadlock-plugins/deadlock-extension/src/core/mission/model/userChallenge.ts
similarity index 97%
rename from deadlock-plugins/deadlock-extension/src/core/mission/models/userChallenge.ts
rename to deadlock-plugins/deadlock-extension/src/core/mission/model/userChallenge.ts
index 9abad84f5038f6b7922d8b0bf3acacf36d4a1a86..cd1a92fc5e213b715bcb03c3b3530a1ccc243d6f 100644
--- a/deadlock-plugins/deadlock-extension/src/core/mission/models/userChallenge.ts
+++ b/deadlock-plugins/deadlock-extension/src/core/mission/model/userChallenge.ts
@@ -14,6 +14,7 @@ interface UserChallenge {
 export default UserChallenge;
 
 export interface UserDetails {
+  id: string;
   firstName: string;
   lastName: string;
   organization: string;
diff --git a/deadlock-plugins/deadlock-extension/src/core/userConfig.ts b/deadlock-plugins/deadlock-extension/src/core/userConfig.ts
index cc6a654a827011a533ba80ff99d130e4a9360a1c..39a5f8b20dcf87cea9810b8605b9f9d4ea35f29a 100644
--- a/deadlock-plugins/deadlock-extension/src/core/userConfig.ts
+++ b/deadlock-plugins/deadlock-extension/src/core/userConfig.ts
@@ -14,10 +14,12 @@
  * "missionId":"code_persist_cdb_crud"
  * }
  */
+import { Uri, workspace } from 'vscode';
 import { recorderError as error } from '../recorder/utils/log';
-import { UserDetails } from './mission/models/userChallenge';
+import { USER_CHALLENGE_PATH } from './config';
+import { UserDetails } from './mission/model/userChallenge';
 
-export default abstract class UserConfig {
+export default class UserConfig {
   private userConfigJson: any | undefined;
 
   getPaths(): Map<number, string> {
@@ -63,12 +65,11 @@ export default abstract class UserConfig {
     return this.userConfigJson?.remoteUserDetails;
   }
 
-  getCurrentUserId(): string {
-    return this.userConfigJson?.currentUserId;
+  async loadText(): Promise<string> {
+    const textDocument = await workspace.openTextDocument(Uri.parse(USER_CHALLENGE_PATH));
+    return Promise.resolve(textDocument.getText());
   }
 
-  abstract loadText(): Promise<string>;
-
   public async init() {
     try {
       const userConfig = await this.loadText();
diff --git a/deadlock-plugins/deadlock-extension/src/core/utils/mission.utils.ts b/deadlock-plugins/deadlock-extension/src/core/utils/mission.utils.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d279e45fc4f9d44ad328c917658a1d7b6f7f7ceb
--- /dev/null
+++ b/deadlock-plugins/deadlock-extension/src/core/utils/mission.utils.ts
@@ -0,0 +1,21 @@
+import { PathLike, readFileSync } from 'fs';
+import { join } from 'path';
+import { missionWorkdir, USER_CHALLENGE_PATH } from '../config';
+import UserChallenge from '../mission/model/userChallenge';
+import isDocker from './isdocker';
+
+export function getReviewedStudentWorkdirPath(userId: string): string {
+  return join(missionWorkdir, 'students', `${userId}`);
+}
+
+export function getUserChallenge(userId: string, missionid: string, isReviewing = false): UserChallenge {
+  let path: number | PathLike;
+  if (isDocker()) {
+    path = USER_CHALLENGE_PATH;
+  } else if (isReviewing) {
+    path = join(getReviewedStudentWorkdirPath(userId), missionid, '.config', 'userChallenge.json');
+  } else {
+    path = join(missionWorkdir, missionid, '.config', 'userChallenge.json');
+  }
+  return JSON.parse(readFileSync(path, 'utf8'));
+}
diff --git a/deadlock-plugins/deadlock-extension/src/extension.ts b/deadlock-plugins/deadlock-extension/src/extension.ts
index 7aaf21e1dc8c32b9fc0325baf3485b211d6f76b5..a4f51b356bee9808a5b49e917018e5581fecf6ce 100644
--- a/deadlock-plugins/deadlock-extension/src/extension.ts
+++ b/deadlock-plugins/deadlock-extension/src/extension.ts
@@ -1,15 +1,14 @@
 import { window, ExtensionContext, workspace, commands } from 'vscode';
 import Controller from './core/controller';
+import UserConfig from './core/userConfig';
 import isDocker from './core/utils/isdocker';
 import Recorder from './recorder/recorder';
 import { extensionError as error } from './recorder/utils/log';
 import { DepNodeProvider } from './theia/deadlockPanel';
-import UserConfigTheia from './theia/userConfigTheia';
 import { CommandTreeProvider } from './view/CommandTree';
 import StartedMissionsView from './view/startedMissionsView';
 
-// TODO: refactor remove this
-export const userConfig = new UserConfigTheia();
+export const userConfig = new UserConfig();
 
 export async function runTimer(userId: string, missionId: string, context: ExtensionContext) {
   const apiService = Controller.getInstance(context).apiService;
@@ -54,6 +53,6 @@ export async function activate(context: ExtensionContext) {
       error(JSON.stringify(e));
       window.showErrorMessage("Le recorder n'a pas pu être lancé");
     }
-    runTimer(userConfig.getCurrentUserId(), userConfig.getMissionId(), context);
+    runTimer(userConfig.getCurrentUserDetails().id, userConfig.getMissionId(), context);
   }
 }
diff --git a/deadlock-plugins/deadlock-extension/src/theia/userConfigTheia.ts b/deadlock-plugins/deadlock-extension/src/theia/userConfigTheia.ts
deleted file mode 100644
index 7bdeb915facb96639e2e930c77673648772f627d..0000000000000000000000000000000000000000
--- a/deadlock-plugins/deadlock-extension/src/theia/userConfigTheia.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import UserConfig from '../core/userConfig';
-
-import { USER_CHALLENGE_PATH } from '../core/config';
-import { Uri, workspace } from 'vscode';
-
-export default class UserConfigTheia extends UserConfig {
-  async loadText(): Promise<string> {
-    const textDocument = await workspace.openTextDocument(Uri.parse(USER_CHALLENGE_PATH));
-    return Promise.resolve(textDocument.getText());
-  }
-}
diff --git a/deadlock-plugins/deadlock-extension/src/view/startedMissionsView.ts b/deadlock-plugins/deadlock-extension/src/view/startedMissionsView.ts
index 75378b46601b5ba45e649f4a994a70d977b8e44e..aaff928f3f95c3f0f749ea25e6a90b0e3ba84297 100644
--- a/deadlock-plugins/deadlock-extension/src/view/startedMissionsView.ts
+++ b/deadlock-plugins/deadlock-extension/src/view/startedMissionsView.ts
@@ -1,13 +1,12 @@
 import { randomBytes } from 'crypto';
 import { existsSync, readdirSync, readFileSync } from 'fs';
 import { join } from 'path';
-import { ExtensionContext, Webview, WebviewView, WebviewViewProvider, window } from 'vscode';
-import { missionWorkdir } from '../core/config';
+import { ExtensionContext, Webview, WebviewView, WebviewViewProvider } from 'vscode';
 import Controller from '../core/controller';
-import UserChallenge from '../core/mission/models/userChallenge';
+import UserChallenge from '../core/mission/model/userChallenge';
 import { extensionWarn } from '../recorder/utils/log';
 import { getUri } from './webviewBase';
-
+import { missionWorkdir } from '../core/config';
 export default class StartedMissionsView implements WebviewViewProvider {
   private readonly controller: Controller;
   constructor(private context: ExtensionContext) {
@@ -27,10 +26,9 @@ export default class StartedMissionsView implements WebviewViewProvider {
   onMessageReceive(message: any): void {
     switch (message.command) {
       case 'openMission': {
-        window.showInformationMessage('click received: ' + message.mission);
         const path = join(missionWorkdir, message.mission, '.config', 'user-challenge.json');
         const userChallenge: UserChallenge = JSON.parse(readFileSync(path, 'utf8'));
-        this.controller.launchMission(userChallenge.missionId, userChallenge.missionVersion);
+        Controller.getInstance().launchMission(userChallenge.missionId, userChallenge.missionVersion);
         return;
       }
     }