diff --git a/documentation/Hyperdrive.md b/documentation/Hyperdrive.md index 4f09df787c08cbc7c8c6665f404937f11599788d..67b3836ec7ed5b0c4856155cfccf998ed2264690 100644 --- a/documentation/Hyperdrive.md +++ b/documentation/Hyperdrive.md @@ -44,6 +44,7 @@ Paschoud Nicolas : - Requêtes SQL (sql-request.js) - Affichage de l'arborescence dans le drive - Affichage des informations du fichier +- Création d'un dossier ## Architecture @@ -71,675 +72,153 @@ Pour la réalisation de ce projet, nous avons utilisé la plateform Node JS pour ## Routes -"use strict"; +### / -const CryptoJS = require("crypto-js"); +La route principale retourne la page principale du site (index.html) -const http = require("http"); +### /login +Cette route permet de créer un token pour l'utilisateur si il est inscrit au site +Paramètre : -const express = require('express'); +- pseudo : Pseudo de l'utilisateur +- password : Mot de passe de l'utilisateur -const app = express(); +Retour : -const port = 8080; - -const sql = require('./sql-request'); - - - - - -///// JWT part ///// - - - -var valid_tokens = []; - - - -String.prototype.hashCode = function() { - - var hash = 0, i, chr; - - if (this.length === 0) return hash; - - for (i = 0; i < this.length; i++) { - - chr = this.charCodeAt(i); - - hash = ((hash << 5) - hash) + chr; - - hash |= 0; // Convert to 32bit integer - - } - - return hash; - -}; - - - -function tob64(elem){ - - return Buffer.from(elem.toString()).toString('base64').slice(0, -2); - -} - - - -function Header(typ, alg){ - - this.typ = typ; - - this.alg = alg; - - - - this.toString = function(){ return "{" + this.typ + "," + this.alg + "}"}; - -} - - - -function Payload(user, pass_enc){ - - this.user = user; - - this.pass_enc = pass_enc; - - - - this.toString = function(){ return "{" + this.user + "," + this.pass_enc + "}"}; - - - -} - - - -function Signature(token){ - - const secret = "our super hyperdrive secret" + new Date(); - - return CryptoJS.HmacSHA512(token, secret); - -} - - - -function JWT(pl_user, pl_pass){ - - this.header = new Header("jwt", "HS512"); - - this.payload = new Payload(pl_user, pl_pass.hashCode()); - - let token = tob64(this.header) + "." + tob64(this.payload); - - let signature = new Signature("token"); - - this.signedToken = token + "." + signature; - -} - - - - - -function add_token(token, user) { - - - - for (let i = 0; i < valid_tokens.length; i++) { - - if(Object.keys(valid_tokens[i])[0] == token){ - - valid_tokens.splice(i, 1); - - console.log("Unable to add token. (token already present)"); - - break; - - } - - } - - let obj = {}; obj[token.toString()] = user; - - valid_tokens.push(obj); - - console.log(valid_tokens) - - - - console.log("Successfully added token."); - - - - +Le retour de cette route est un objet JSON formé de cette manière : +```json +{ + "route": "/login", + "resCode": 0, + "signedToken": jwt.signedToken, + "comment": `Password for user '${ user }' true.` } +``` -function remove_token(token) { - +### /logout +Logout permet de supprimer un token lorsqu'un utilisateur se deconnecte. - for (let i = 0; i < valid_tokens.length; i++) { +Param : - if(Object.keys(valid_tokens[i])[0] == token){ +- Token : Token de l'utilisateur a déconnecter - valid_tokens.splice(i, 1); +### /register - console.log("Successfully removed token from valid_tokens."); +Cette route permet d'inscrire un utilisateur au service de l'hyperdrive - return true; +Paramètres : - } +- pseudo : Pseudo du nouvel utilisateur +- password : Mot de passe du nouvel utilisateur - } +### /share/:file_id/:to_user +Cette route permet de partager un fichier avec un utilisateur +Paramètres : - console.log("Unable to remove token from valid_tokens. (Token not present)"); +- token : Il s'agit du token de l'utilisateur qui souhaite partage un fichier +- file_id : Il s'agit de l'id du fichier à partager +- to_user : Il s'agit de la personne à qui on souhaite partager le fichier +### /upload +Cette fonction permet d'uploader un fichier dans un path. +Paramètre : +- token : Token d'authentification de l'utilisateur. +- file_name : Il s'agit du nom du fichier. -} +### /download/:file_id +Cette fonction permet de télécharger un fichier. +Paramètre : -// verify the token +- file_id : Id du fichier que l'on souhaite télécharger. +- token : Token d'authentification de l'utilisateur. -// return : user if exist +### /change-path* -function verify_token(token) { +Cette fonction permet d'afficher le contenu d'un dossier. - for (let i = 0; i < valid_tokens.length; i++) { +Paramètres : - if(Object.keys(valid_tokens[i])[0] == token) +- token : Token d'authentification de l'utilisateur. +- path : Il s'agit du dossier dont le contenu doit être affiché. - return valid_tokens[i][token]; +Retour : - } +Cette route retour un tableau d'objet JSON. Chaque object est soit un dossier, soit un fichier - return false; +Voici l'exemple d'un objet fichier. Cet objet se trouve dans un array +```json +{ + "paths": "/a", + "login": "a", + "parent": null, + "file_id": "ab", + "file_name": "deux" } +``` +Voici l'exemple d'un objet dossier. Cet objet se trouve dans un array - - - -///// End JWT part ///// - - - - - -app.get('/', (req, res) => { - - res.sendFile(__dirname + '/front/index.html'); - -}); - - - -/* Login - - \* param : pseudo - - \* param : password - - */ - -// resCode : [ 0: User now logged in, 1: False password, 2: Invalid username, 3: Empty user or pass ] - -app.get('/login', (req, res) => { - - - - const user = req.query['user']; - - const pass = req.query['pass']; - - sql.userExist(user, pass, (element) => { - - if (element) - - check_login(user, pass, element, res); - - }); - - - -}); - - - -function check_login(user, pass, userObject, res) { - - if (!user || !pass) { - - res.send({ - - "route": "/login", - - "resCode": 4, - - "comment": "Please enter a username and a password." - - }) - - } - - else{ - - if (userObject){ - - if (userObject.passwd == pass.hashCode()) { - - let jwt = new JWT(user, pass); - - - - res.send({ - - "route": "/login", - - "resCode": 0, - - "signedToken": jwt.signedToken, - - "comment": `Password for user '${ user }' true.` - - }) - - - - add_token(jwt.signedToken, user); - - - - } - - else { - - res.send({ - - "route": "/login", - - "resCode": 1, - - "comment": `Password for user '${ user }' false.` - - }) - - } - - } - - else { - - res.send({ - - "route": "/login", - - "resCode": 2, - - "comment": `Username '${ user }' don't exist.` - - }) - - } - - } - +```json +{ + "paths": "/a/coucou", + "login": "a", + "parent": "/a", + "file_id": null, + "file_name": null } +``` +Un dossier possède un parent, car il se trouve dans un dossier. Dans le cas du dossier, le champ *path* indique la ou se trouve le fichier ainsi que son nom. Le dernier élément est le nom, tandis que tout ce qui se trouve avant est la ou est stocké le fichier. +A l'inverse, un fichier se trouve dans un dossier, il a donc un *path*. Il est certe enfant d'un dossier, mais la seule information de ou il se trouve nous suffit. -// resCode : [ 0: Token is valid, 1: Token is not valid, 3: Empty token ] - -app.get('/testmytoken', (req, res) => { - - - - let token = req.query['token']; - - - - if (!token) { +### /create-path* - res.send({ +Cette fonction permet de créer un dossier à un endroit spécifique. - "resCode": 3, - - "comment": "Please enter a token." - - }) - - } - - - - if (verify_token(token)){ - - res.send({ - - "resCode": 0, - - "comment": "Your token is valid." - - }) - - } - - else { - - res.send({ - - "resCode": 1, - - "comment": "Your token is not valid." - - }) - - } - - - -}) - - - -// resCode : [ 0: Logout ok, 1: Already logged out, 3: Empty token ] - -app.get('/logout/', (req, res) => { - - - - let token = req.query['token']; - - - - if (!token) { - - res.send({ - - "resCode": 3, - - "comment": "Please enter a token." - - }) - - } - - - - else { - - if (verify_token(token)){ - - remove_token(token); - - res.send({ - - "resCode": 0, - - "comment": "Your are now logged out." - - }) - - } - - else { - - res.send({ - - "resCode": 1, - - "comment": "Your are already logged out." - - }) - - } - - } - - - - - -}) - - - -/** - - \* Request register - - \* param : pseudo - - \* param : password - - */ - -app.get('/register/', (req, res) => { - - sql.addUser(req.query['login'], req.query['pass']); - - res.send(`Request for a register (${req.query['login']}, ${req.query['pass']})`); - -}) - - - -/** - - \* Request to share a file with a user - - \* param : file_id - - \* param : user1 - - \* param : user2 - - \* user1 share a file_id with user2 - - */ - -app.get('/share/:file_id/:to_user', (req, res) => { - - - - let token = req.query["token"] - - let user = verify_token(token); - - console.log("user : " + user) - - - - if (req.params['to_user'] && req.params['file_id']){ - - let to_user = req.params['to_user']; - - let file_id = req.params['file_id']; - - sql.addSharing(user, to_user, file_id).then(function (r) { - - res.send(r); - - }) - - } - - else{ - - res.send("Unable to share. Please provide a user to share with and a file_id."); - - } - -}) - - - -/** - - \* Request to upload a file - - */ - -app.get('/upload/', (req, res) => { - - let d = new Date(); - - let date_upload = d.getTime(); - - // "abcd", "un", "/a", 46.2054, 6.1459, date_upload - - - - http.get('http://bot.whatismyipaddress.com', (res) => { - - res.setEncoding('utf8'); - - res.on('data', function(chunk){ - - console.log(chunk); - - let ip = chunk; - - http.get('http://ip-api.com/json/' + ip, (resp) => { - - let data = ''; - - resp.on('data', (chunk) => { - - data += chunk; - - }); - - - - resp.on('end', () => { - - console.log(JSON.parse(data)); - - }); - - }); - - }); - - }); - - - - res.send(`Request for an upload (${req.query['file']})`) - -}); - - - -app.get('/download/:file_id', (req, res) => { - - let token = req.query["token"] - - let file_id = req.params["file_id"] - - - - let user = verify_token(token); - - if (user){ - - sql.verifyFileID(user, file_id, (filename) => { - - console.log(filename) - - if (filename){ - - res.download("files/" + file_id, filename); - - } - - else{ - - res.send("Can't download (not your file).") - - } - - }) - - } - - else{ - - res.send("Can't download (please be connected).") - - } - -}) - - - -/** - - \* This function return the content of a new path - - \* param - - */ - -app.get('/change-path*', (req, res) => { - - let path = req.params['0'].split("/"); - - path.pop(); - - path = path.join("/"); - - let tok = req.params['0'].split("/").pop(); - - let name = verify_token(tok); - - if (name) { - - let content = sql.changeDirectory(name, path, - - (content) => { - - res.send(content); +Paramètres : - }); - } -}) +### /get-info +La route get-info nous permet de récupérer les informations d'un fichier. +Paramètres : -app.get('/create-path*', (req, res) => +- file_id : Id du fichier dont on souhaite avoir les informations. +- token : Il s'agit du token d'authentification. -### /get-info +### /show-shared-file -La route get-info nous permet de récupérer les informations d'un fichier +Cette route permet de récupérer tous les fichiers partagé avec un utilisateur. -Paramètres : +Paramètres : -- file_id : Id du fichier dont on souhaite avoir les informations -- token : Il s'agit du token d'authentification +- token : Le token nous permet de récupérer l'id de l'utilisateur. -### /show-shared-file +Retour : +La réponse est un tableau d'objet JSON. Chaque objet contient ces informations : +```json +``` +## Conclusion -\- Une conclusion \ No newline at end of file +Lors du développement de ce drive, nous avons pu utiliser des technologies nouvelles ainsi qu'un manière intéressante de dévelloper. La programmation asynchrone fut difficile à prendre en main, mais nous y somme arrivé. \ No newline at end of file diff --git a/projet/hyperdrive-rest.js b/projet/hyperdrive-rest.js index db1154e9db9c5d5489ee8d014d3abc4b07640225..d07ff335cbc53c8a3ec1a49214db2db02af672e3 100644 --- a/projet/hyperdrive-rest.js +++ b/projet/hyperdrive-rest.js @@ -308,8 +308,8 @@ app.get('/download/:file_id', (req, res) => { }) /** - * This function return the content of a new path - * param + * This function return the content of a path + * param path : Path of the folder we want to show */ app.get('/change-path*', (req, res) => { let path = req.params['0'].split("/"); @@ -318,7 +318,7 @@ app.get('/change-path*', (req, res) => { let tok = req.params['0'].split("/").pop(); let name = verify_token(tok); if (name) { - let content = sql.changeDirectory(name, path, + sql.changeDirectory(name, path, (content) => { res.send(content); }); @@ -363,6 +363,9 @@ app.get('/get-info', (req, res) => { } }); +/** + * + */ app.get('/show-shared-file', (req, res) => { let token = req.query["token"]; let name = verify_token(token);