Update
This commit is contained in:
		
							parent
							
								
									f2194b4ebe
								
							
						
					
					
						commit
						ea444b350c
					
				
							
								
								
									
										5
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -101,6 +101,11 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", |       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", | ||||||
|       "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" |       "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" | ||||||
|     }, |     }, | ||||||
|  |     "bcryptjs": { | ||||||
|  |       "version": "2.4.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", | ||||||
|  |       "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" | ||||||
|  |     }, | ||||||
|     "binary": { |     "binary": { | ||||||
|       "version": "0.3.0", |       "version": "0.3.0", | ||||||
|       "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", |       "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", | ||||||
|  | |||||||
| @ -6,6 +6,7 @@ | |||||||
|     "test": "echo \"Error: no test specified\" && exit 1" |     "test": "echo \"Error: no test specified\" && exit 1" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|  |     "bcryptjs": "^2.4.3", | ||||||
|     "express": "^4.16.4", |     "express": "^4.16.4", | ||||||
|     "express-fileupload": "^1.1.3-alpha.1", |     "express-fileupload": "^1.1.3-alpha.1", | ||||||
|     "pug": "^2.0.3", |     "pug": "^2.0.3", | ||||||
|  | |||||||
							
								
								
									
										163
									
								
								server.js
									
									
									
									
									
								
							
							
						
						
									
										163
									
								
								server.js
									
									
									
									
									
								
							| @ -8,12 +8,14 @@ const { spawn } = require('child_process'); | |||||||
| const pug = require('pug'); | const pug = require('pug'); | ||||||
| const unzip = require('unzip'); | const unzip = require('unzip'); | ||||||
| const touch = require('touch'); | const touch = require('touch'); | ||||||
|  | const bcrypt = require('bcryptjs'); | ||||||
| 
 | 
 | ||||||
| // Consts
 | // Consts
 | ||||||
| const port = 8000; | const port = 8000; | ||||||
| const pythonPath = '/home/pytron/miniconda3/envs/pytron/bin/python' | const pythonPath = '/usr/bin/python3' | ||||||
| const aisPath = 'pytron_run/ai_manager/' | const aisPath = 'pytron_run/ai_manager/' | ||||||
| const aisPathOld = 'pytron_run/ai_manager_old' | const aisPathOld = 'pytron_run/ai_manager_old' | ||||||
|  | const hashPath = "__bcrypt__hash.txt" | ||||||
| 
 | 
 | ||||||
| // Create the directories to store the files
 | // Create the directories to store the files
 | ||||||
| try { fs.mkdirSync(aisPath); } catch { } | try { fs.mkdirSync(aisPath); } catch { } | ||||||
| @ -98,13 +100,41 @@ function parse(data) { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     parsed.sortedAis.sort((a, b) => b.score - a.score); |     parsed.sortedAis.sort((a, b) => b.score - a.score); | ||||||
|     parsed.sortedAis[0].rank = 1; |     if (parsed.sortedAis.length > 0) parsed.sortedAis[0].rank = 1; | ||||||
|     parsed.sortedAis[1].rank = 2; |     if (parsed.sortedAis.length > 1) parsed.sortedAis[1].rank = 2; | ||||||
|     parsed.sortedAis[2].rank = 3; |     if (parsed.sortedAis.length > 2) parsed.sortedAis[2].rank = 3; | ||||||
| 
 | 
 | ||||||
|     return parsed; |     return parsed; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | function saveArchiveAndRun(req, res) { | ||||||
|  | 
 | ||||||
|  |     let path = pathtools.join(aisPath, req.body.name); | ||||||
|  |     try { fs.mkdirSync(path); } catch { } | ||||||
|  | 
 | ||||||
|  |     let zipfile = pathtools.join(path, 'archive.zip'); | ||||||
|  |     req.files.archive.mv(zipfile, (err) => { | ||||||
|  |         if (err != null) { | ||||||
|  |             console.log(err); | ||||||
|  |             res.render('error', {message: 'Unable to save the ZIP archive to the server'}); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         fs.createReadStream(zipfile) | ||||||
|  |             .pipe(unzip.Extract({path})) | ||||||
|  |             .on('close', () => { | ||||||
|  |                 // Touch __init__.py
 | ||||||
|  |                 touch(pathtools.join(path, '__init__.py'), () => { | ||||||
|  |                     // Trigger python_run
 | ||||||
|  |                     runPython(); | ||||||
|  |                     res.redirect('/'); | ||||||
|  |                 }); | ||||||
|  |             }) | ||||||
|  |             .on('error', () => { | ||||||
|  |                 res.render('error', {message: 'Failed to unzip the archive'}); | ||||||
|  |             }); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| function startServer() { | function startServer() { | ||||||
|     const app = express(); |     const app = express(); | ||||||
|     app.set('view engine', 'pug'); |     app.set('view engine', 'pug'); | ||||||
| @ -134,6 +164,10 @@ function startServer() { | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         if (!req.body.password) { | ||||||
|  |             res.render('error', {message: "You have to enter a password in the form"}); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         if (req.body.name.indexOf('.') !== -1) { |         if (req.body.name.indexOf('.') !== -1) { | ||||||
|             res.render('error', {message: "The name of your AI can't contain dots"}); |             res.render('error', {message: "The name of your AI can't contain dots"}); | ||||||
|         } |         } | ||||||
| @ -143,54 +177,89 @@ function startServer() { | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let path = pathtools.join(aisPath, req.body.name) |         let path = pathtools.join(aisPath, req.body.name); | ||||||
| 
 |         let aiExisted; | ||||||
|         try { |         try { | ||||||
|             if (fs.statSync(path).isDirectory()) { |             fs.statSync(path).isDirectory(); | ||||||
|                 // Move it to old
 |             aiExisted = true; | ||||||
|                 let version = 0; |         } catch (e) { | ||||||
|                 for(;;) { |             aiExisted = false; | ||||||
|                     let movePath = pathtools.join(aisPathOld, req.body.name + '.' + version); |             fs.mkdirSync(path); | ||||||
|                     try { |  | ||||||
|                         fs.statSync(movePath); |  | ||||||
|                         // If the sync succeded, it means that the directory already exists
 |  | ||||||
|                         version++; |  | ||||||
|                     } catch { |  | ||||||
|                         // If we're here, it means that we found the right path. We
 |  | ||||||
|                         // will move the old one to the old directories, and save
 |  | ||||||
|                         // the new one
 |  | ||||||
|                         fs.renameSync(path, movePath); |  | ||||||
|                         break; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } catch { |  | ||||||
|             // Nothing to do here
 |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         fs.mkdirSync(path); |  | ||||||
| 
 | 
 | ||||||
|         let zipfile = pathtools.join(path, 'archive.zip'); |         if (aiExisted) { | ||||||
|         req.files.archive.mv(zipfile, (err) => { |             fs.readFile(pathtools.join(path, hashPath), 'utf-8', function(err, data) { | ||||||
|             if (err != null) { | 
 | ||||||
|                 console.log(err); |                 if (err != null) { | ||||||
|                 res.render('error', {message: 'Unable to save the ZIP archive to the server'}); |                     res.render('error', {message: "Couldn't read hashed password"}); | ||||||
|                 return; |                     console.log(err); | ||||||
|             } |                     return; | ||||||
|             fs.createReadStream(zipfile) |                 } | ||||||
|                 .pipe(unzip.Extract({path})) | 
 | ||||||
|                 .on('close', () => { |                 // If the AI already existed, verify the password
 | ||||||
|                     // Touch __init__.py
 |                 bcrypt.compare(req.body.password, data, function(err, success) { | ||||||
|                     touch(pathtools.join(path, '__init__.py'), () => { |                     if (err != null) { | ||||||
|                         // Trigger python_run
 |                         res.render('error', {message: "Couldn't compare password"}); | ||||||
|                         runPython(); |                         return; | ||||||
|                         res.redirect('/'); |                     } | ||||||
|                     }); | 
 | ||||||
|                 }) |                     if (!success) { | ||||||
|                 .on('error', () => { |                         res.render('error', {message: "Authentication failed"}); | ||||||
|                     res.render('error', {message: 'Failed to unzip the archive'}); |                         return; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     try { | ||||||
|  |                         if (fs.statSync(path).isDirectory()) { | ||||||
|  |                             // Move it to old
 | ||||||
|  |                             let version = 0; | ||||||
|  |                             for(;;) { | ||||||
|  |                                 let movePath = pathtools.join(aisPathOld, req.body.name + '.' + version); | ||||||
|  |                                 try { | ||||||
|  |                                     fs.statSync(movePath); | ||||||
|  |                                     // If the sync succeded, it means that the directory already exists
 | ||||||
|  |                                     version++; | ||||||
|  |                                 } catch { | ||||||
|  |                                     // If we're here, it means that we found the right path. We
 | ||||||
|  |                                     // will move the old one to the old directories, and save
 | ||||||
|  |                                     // the new one
 | ||||||
|  |                                     fs.renameSync(path, movePath); | ||||||
|  |                                     break; | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } catch { | ||||||
|  |                         // Nothing to do here
 | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     // Save archive and run stuff
 | ||||||
|  |                     saveArchiveAndRun(req, res); | ||||||
|                 }); |                 }); | ||||||
|         }); |             }); | ||||||
|  |         } else { | ||||||
|  |             bcrypt.hash(req.body.password, 10, function(err, hash) { | ||||||
|  | 
 | ||||||
|  |                 if (err != null) { | ||||||
|  |                     res.render('error', {message: "Couldn't hash password"}); | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 // Store hash in your password DB.
 | ||||||
|  |                 fs.writeFile(pathtools.join(path, hashPath), hash, (err) => { | ||||||
|  | 
 | ||||||
|  |                     if (err != null) { | ||||||
|  |                         res.render('error', {message: "Couldn't save hashed password"}); | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     // Save archive and run stuff
 | ||||||
|  |                     saveArchiveAndRun(req, res); | ||||||
|  | 
 | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     app.use('/static', express.static('static')); |     app.use('/static', express.static('static')); | ||||||
|  | |||||||
| @ -16,11 +16,18 @@ block content | |||||||
|                             p.content.has-text-justified |                             p.content.has-text-justified | ||||||
|                                 | You can use an already existing name to |                                 | You can use an already existing name to | ||||||
|                                 | replace it with a new version of your AI. |                                 | replace it with a new version of your AI. | ||||||
|                             p.content.has-text-justified |  | ||||||
|                                 | You could also erase other people's AI, but |  | ||||||
|                                 | please, don't do it, because I would be sad |  | ||||||
|                                 | 😢 |  | ||||||
|                             input.input(type="text", name="name", placeholder="Name of your AI") |                             input.input(type="text", name="name", placeholder="Name of your AI") | ||||||
|  |                         .fielg | ||||||
|  |                             label.label Password | ||||||
|  |                             p.content.has-text-justified | ||||||
|  |                                 | This password will allow you to update your | ||||||
|  |                                 | AI.  If the name you specify is not used, | ||||||
|  |                                 | this password can be anything you want. If | ||||||
|  |                                 | the name you specify already exists, you need | ||||||
|  |                                 | to enter the password you entered when you | ||||||
|  |                                 | uploaded the AI the first time. | ||||||
|  |                             input.input(type="password", name="password", placeholder="Password") | ||||||
|  | 
 | ||||||
|                         .field |                         .field | ||||||
|                             label.label Archive |                             label.label Archive | ||||||
|                             p.content.has-text-justified |                             p.content.has-text-justified | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user