From c153385c40fd8ac5f8dea520e27d4a02417f1ec1 Mon Sep 17 00:00:00 2001 From: Juan Date: Tue, 5 Jul 2022 13:34:59 +0200 Subject: [PATCH] Correction + sujet eval et update session3 --- b3-dev/node/eval/api.js | 167 +++++++++++++++++++++ b3-dev/node/eval/config.json | 7 + b3-dev/node/eval/create-et-grant.sql | 12 ++ b3-dev/node/eval/eval.api/api.js | 129 ++++++++++++++++ b3-dev/node/eval/eval.api/config.json | 7 + b3-dev/node/eval/eval.api/package.json | 16 ++ b3-dev/node/eval/front.js | 74 +++++++++ b3-dev/node/eval/index.js | 85 +++++++++++ b3-dev/node/eval/package.json | 18 +++ b3-dev/node/eval/sujet.md | 11 ++ b3-dev/node/eval/users.sql | 46 ++++++ b3-dev/node/session3/config.json/config.local.json | 24 +++ b3-dev/node/session3/config.json/package.json | 12 ++ 13 files changed, 608 insertions(+) create mode 100644 b3-dev/node/eval/api.js create mode 100644 b3-dev/node/eval/config.json create mode 100644 b3-dev/node/eval/create-et-grant.sql create mode 100644 b3-dev/node/eval/eval.api/api.js create mode 100644 b3-dev/node/eval/eval.api/config.json create mode 100644 b3-dev/node/eval/eval.api/package.json create mode 100644 b3-dev/node/eval/front.js create mode 100644 b3-dev/node/eval/index.js create mode 100644 b3-dev/node/eval/package.json create mode 100644 b3-dev/node/eval/sujet.md create mode 100644 b3-dev/node/eval/users.sql create mode 100644 b3-dev/node/session3/config.json/config.local.json create mode 100644 b3-dev/node/session3/config.json/package.json diff --git a/b3-dev/node/eval/api.js b/b3-dev/node/eval/api.js new file mode 100644 index 0000000..4acef75 --- /dev/null +++ b/b3-dev/node/eval/api.js @@ -0,0 +1,167 @@ +/* + Ecrire une API en node, tournant sur le port 8088, + permettant de vérifier qu'un utilisateur est existant dans une + base de donnée "sécurisée" dans laquelle le mot de passe est + stocké en MD5. + Les informations de connexion seront stockées en json. + + Votre réponse sera sous forme d'un zip. + Elle contiendra au minimum : + - un fichier SQL pour la création de la base avec un utilisateur dédié + - un deuxième fichier SQL pour la création de la table et ajoutant un au moins un utilisateur à la table + - un fichier README indiquant comment installer votre projet et les routes disponibles + - un fichier package.json + - un fichier api.js contenant votre code Node +*/ + + // testing : + // https://mariadb.com/kb/en/nodejs-connector/ + + import http from 'http'; // to create server + import url from 'url'; // to parse url + import fs from 'fs'; // to load config + + // https://www.npmjs.com/package/email-validator + // pour vérifier que le mail est un mail valid : + import validator from 'email-validator'; + + // pour valider le mot de passe + import md5 from 'md5'; + + // on ajoute la possibilité de require du json en objet + import { createRequire } from 'module'; + const require = createRequire(import.meta.url); + + const BASIC_API_PORT = 8088; + + var config=null; + if(fs.existsSync(process.cwd() + '/config.json')){ + config = require(process.cwd() + '/config.json'); + } + else { + console.log('no config'); + exit(0); + } + + const mariadb = require('mariadb'); + const { exit } = require('process'); + const pool = mariadb.createPool({ + host: config.DB_HOST, + port: config.DB_PORT, + user: config.DB_USR, + password:config.DB_PWD, + database: config.DB_NAME, + connectionLimit: 5, + }); + + //const server = http.createServer(function (req, resp) { + const app = http.createServer + ( + async (req, res) => + { + const parsedURL = url.parse(req.url, true); + let response_json = JSON.stringify({"up":false}); + if(req.method === 'GET' && parsedURL.pathname.startsWith('/up')) + { + var cnx = null; + try + { + cnx=await pool.getConnection(); + const tables_res = await cnx.query("SHOW TABLES"); + if(tables_res.length > 0) + { + response_json = JSON.stringify({'up':true}); + } + } + catch(err) + { + console.log(err); + res.statusCode = 400; + res.end(response_json); + if(cnx) + { + return cnx.end(); + } + throw(err); + } + finally + { + res.statusCode = 200; + res.end(response_json); + if(cnx) + { + return cnx.end(); + } + } + } + else if(req.method === 'POST' && parsedURL.pathname.startsWith('/check')) + { + console.log("checking :"); + let responseString = ""; + req.on('data', function (varposted) { + responseString += varposted; + }).on('end', async function () { + if(responseString.indexOf('?')<0) { + responseString = '?'+responseString; + } + let parsedData = url.parse(responseString, true); + console.log("ParsedData", parsedData); + let response_content = {'up':false,'emailtocheck':''}; + if(parsedData.query['email'] && parsedData.query['password']) { + response_content.emailtocheck = parsedData.query['email']; + response_content.hashedpassword = md5(parsedData.query['password']); + if(validator.validate(response_content.emailtocheck)) + { + cnx=await pool.getConnection(); + //let query="SELECT * FROM users WHERE courriel = '" + response_content.emailtocheck +"'"; + let query="SELECT * FROM users WHERE courriel = ? AND mot_de_passe = ?"; + console.log('query : ',query,' with ? = ', response_content.emailtocheck); + const email_res = await cnx.query(query, [response_content.emailtocheck, response_content.hashedpassword]); + if(email_res.length > 0) + { + response_content.up=true; + response_content.emailValid=true; + } + else + { + response_content.up=true; + response_content.emailValid=false; + response_content.error='Not Found'; + response_content.error_code=404; + } + res.statusCode = 200; + res.end(JSON.stringify(response_content)); + if(cnx) + { + return cnx.end(); + } + } + else { + response_content.up=true; + response_content.emailValid=false; + response_content.error='I\'m a teapot'; + response_content.error_code=418; + res.statusCode = 200; + res.end(JSON.stringify(response_content)); + } + } + else { + response_content.up=true; + response_content.emailValid=false; + response_content.emailtocheck=parsedData.query['email']; + response_content.error='Invalid query mail or password do match requirements'; + response_content.error_code=400; + res.statusCode = 200; + res.end(JSON.stringify(response_content)); + } + }); + } + else + { + res.statusCode = 400; + res.end("API Endpoint Not Supported"); + } + } + ); + app.listen(BASIC_API_PORT); + console.log('mariadb test api started'); diff --git a/b3-dev/node/eval/config.json b/b3-dev/node/eval/config.json new file mode 100644 index 0000000..92b8a40 --- /dev/null +++ b/b3-dev/node/eval/config.json @@ -0,0 +1,7 @@ +{ + "DB_HOST" : "127.0.0.1", + "DB_PORT" : "3306", + "DB_USR" : "eval_user", + "DB_PWD" : "ov62p67t7PId9N3", + "DB_NAME" : "eval_bdd" +} \ No newline at end of file diff --git a/b3-dev/node/eval/create-et-grant.sql b/b3-dev/node/eval/create-et-grant.sql new file mode 100644 index 0000000..7961c79 --- /dev/null +++ b/b3-dev/node/eval/create-et-grant.sql @@ -0,0 +1,12 @@ +CREATE DATABASE IF NOT EXISTS `eval_bdd` + DEFAULT CHARACTER SET utf8 + DEFAULT COLLATE utf8_general_ci; + +GRANT USAGE ON *.* TO "eval_user"@"localhost" IDENTIFIED BY "ov62p67t7PId9N3" + WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0; + +GRANT USAGE ON *.* TO "eval_user"@"%" IDENTIFIED BY "ov62p67t7PId9N3" + WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0; + +GRANT ALL PRIVILEGES ON `eval_bdd`.* TO 'eval_user'@'%'; +GRANT ALL PRIVILEGES ON `eval_bdd`.* TO 'eval_user'@'localhost'; \ No newline at end of file diff --git a/b3-dev/node/eval/eval.api/api.js b/b3-dev/node/eval/eval.api/api.js new file mode 100644 index 0000000..39253b8 --- /dev/null +++ b/b3-dev/node/eval/eval.api/api.js @@ -0,0 +1,129 @@ +/* + Ecrire une API en node, tournant sur le port 8088, + permettant de vérifier qu'un utilisateur est existant dans une + base de donnée "sécurisée" dans laquelle le mot de passe est + stocké en MD5. + Les informations de connexion seront stockées en json. + + Votre réponse sera sous forme d'un zip. + Elle contiendra au minimum : + - un fichier SQL pour la création de la base avec un utilisateur dédié + - un deuxième fichier SQL pour la création de la table et ajoutant un au moins un utilisateur à la table + - un fichier README indiquant comment installer votre projet et les routes disponibles + - un fichier package.json + - un fichier api.js contenant votre code Node +*/ + + // testing : + // https://mariadb.com/kb/en/nodejs-connector/ + + + const http = require ('http'); // to create server + const url = require('url'); // to parse url + const fs = require('fs'); // to load config + const BASIC_API_PORT = 8088; + + var config=null; + if(fs.existsSync(process.cwd() + '/config.json')){ + config = require(process.cwd() + '/config.json'); + } + else { + console.log('no config'); + } + + + const mariadb = require('mariadb'); + const { exit } = require('process'); + const pool = mariadb.createPool({ + host: config.DB_HOST, + port: config.DB_PORT, + user: config.DB_USR, + password:config.DB_PWD, + database: config.DB_NAME, + connectionLimit: 5, + }); + + //const server = http.createServer(function (req, resp) { + const app = http.createServer + ( + async (req, res) => + { + const parsedURL = url.parse(req.url, true); + var response_json = JSON.stringify({"up":false}); + if(req.method === 'GET' && parsedURL.pathname.startsWith('/up')) + { + var cnx = null; + try + { + cnx=await pool.getConnection(); + const tables_res = await cnx.query("SHOW TABLES"); + if(tables_res.length > 0) + { + response_json = JSON.stringify({'up':true}); + } + } + catch(err) + { + console.log(err); + res.statusCode = 400; + res.end(response_json); + if(cnx) + { + return cnx.end(); + } + throw(err); + } + finally + { + res.statusCode = 200; + res.end(response_json); + if(cnx) + { + return cnx.end(); + } + } + } + else if(req.method === 'POST' && parsedURL.pathname.startsWith('/check')) + { + console.log("checking :"); + responseString = "?"; + req.on('data', function (varposted) { + responseString += varposted; + }).on('end', async function () { + parsedData = url.parse(responseString, true); + console.log("ParsedData", parsedData); + let response_content = {'up':false,'emailtocheck':''}; + if(parsedData.query['email']) { + response_content.emailtocheck = parsedData.query['email']; + cnx=await pool.getConnection(); + let query="SELECT * FROM users WHERE courriel = '"+ response_content.emailtocheck +"'"; + console.log(query); + const email_res = await cnx.query(query); + if(email_res.length > 0) + { + response_content.up=true; + response_content.emailValid=true; + } + else + { + response_content.up=true; + response_content.emailValid=false; + } + res.statusCode = 200; + res.end(JSON.stringify(response_content)); + if(cnx) + { + return cnx.end(); + } + } + }); + } + else + { + res.statusCode = 400; + res.end("API Endpoint Not Supported"); + } + } + ); + app.listen(BASIC_API_PORT); + console.log('mariadb test api started'); diff --git a/b3-dev/node/eval/eval.api/config.json b/b3-dev/node/eval/eval.api/config.json new file mode 100644 index 0000000..92b8a40 --- /dev/null +++ b/b3-dev/node/eval/eval.api/config.json @@ -0,0 +1,7 @@ +{ + "DB_HOST" : "127.0.0.1", + "DB_PORT" : "3306", + "DB_USR" : "eval_user", + "DB_PWD" : "ov62p67t7PId9N3", + "DB_NAME" : "eval_bdd" +} \ No newline at end of file diff --git a/b3-dev/node/eval/eval.api/package.json b/b3-dev/node/eval/eval.api/package.json new file mode 100644 index 0000000..8ec3701 --- /dev/null +++ b/b3-dev/node/eval/eval.api/package.json @@ -0,0 +1,16 @@ +{ + "name": "eval", + "version": "1.0.0", + "description": "", + "main": "front.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "mariadb": "^3.0.0", + "md5": "^2.3.0", + "node-fetch": "^3.2.6" + } +} diff --git a/b3-dev/node/eval/front.js b/b3-dev/node/eval/front.js new file mode 100644 index 0000000..210e7d4 --- /dev/null +++ b/b3-dev/node/eval/front.js @@ -0,0 +1,74 @@ +/* + Faire un site en node, tourant sur le port 80. + Le site permet de saisir un email et un mot de passe dans un formulaire. + En retour de soumission du formulaire le site affichera l'email, la chaine MD5 du mot de passe, et l'heure+date de la tentative connexion. +*/ + +/* +Votre réponse sera sous forme d'un zip. +Elle contiendra au minimum : +- un fichier README indiquant comment installer votre projet et les routes disponibles +- un fichier package.json +- un fichier front.js contenant votre code Node +*/ +import http from 'http'; +import * as url from 'url'; + +// npm i md5 +// https://www.npmjs.com/package/md5 +import md5 from 'md5'; + +function outputHTML5(status, response, content, title) +{ + response.writeHead(status, { 'Content-Type': 'text/html; charset=utf-8' }); + response.write( + ` + + + + + ${title} + + + + ${content} + + + ` + ); + response.end(); +} + +var server = http.createServer(function (request, response) { + if(request.url === "/" && request.method==="GET") { + let formHtml = "
"; + formHtml += ""; + formHtml += "
"; + formHtml += "
" + formHtml += "
"; + outputHTML5(200,response,formHtml,"login"); + } + else if(request.url === "/" && request.method==="POST") { + let responseHTML ="informations saisies : "; + let responseString = "?"; + request.on('data', function (varposted) { + responseHTML += varposted; + responseString += varposted; + }).on('end', function () { + let parsedData = url.parse(responseString, true); + console.log("ParsedData", parsedData); + Object.keys(parsedData.query).forEach(function(key) { + var value=parsedData.query[key]; + if(key==='password') { + value=md5(value); + } + responseHTML+= "
"+key+" : "+value; + }); + outputHTML5(200,response,responseHTML,"login"); + }); + } else { + outputHTML5(404,response,'Y\'a rien ici',"Oups"); + } +}); + +server.listen(80); \ No newline at end of file diff --git a/b3-dev/node/eval/index.js b/b3-dev/node/eval/index.js new file mode 100644 index 0000000..546882c --- /dev/null +++ b/b3-dev/node/eval/index.js @@ -0,0 +1,85 @@ +/* +Modifier votre front (code fait à la section 2) pour qu'il interroge +l'API et indique à l'utilisateur si il existe en base de données + +Elle contiendra au minimum : +- un fichier README indiquant comment installer votre projet et les routes disponibles +- un fichier package.json +- un fichier index.js contenant votre code Node +*/ + +import http from 'http'; +import * as url from "url"; +// npm i node-fetch +// https://www.npmjs.com/package/node-fetch +import fetch from 'node-fetch'; + +function outputHTML5(status, response, content, title) +{ + response.writeHead(status, { 'Content-Type': 'text/html; charset=utf-8' }); + response.write( + ` + + + + + ${title} + + + + ${content} + + + ` + ); + response.end(); +} + +var server = http.createServer(function (request, response) { + if(request.url === "/" && request.method==="GET") { + let formHtml = "
"; + formHtml += ""; + formHtml += "
"; + formHtml += "
" + formHtml += "
"; + outputHTML5(200,response,formHtml,"login"); + } + else if(request.url === "/" && request.method==="POST") { + let responseString = "/?"; + console.log("In post"); + request.on('data', function (varposted) { + responseString += varposted; + }).on('end', async function () { + let parsedData = url.parse(responseString, true); + + if(parsedData.query['email']) { + console.log('got' + parsedData.query['email']) + fetch('http://localhost:8088/check', + { + method:'POST', + body:responseString + } + ) + .then(apiresponse => + apiresponse.json() + ) + .then( json => { + if(json.emailValid) { + outputHTML5(200,response,'Ok ! Connexion possible :)',"Cool!"); + } + else { + outputHTML5(200,response,"Cet mail n'existe pas ou le mot de passe ne correspond pas à l'email","Zut!"); + } + }) + .catch(err => { + console.log(err); + outputHTML5(500,response,'Y\'a eu un souci',"Oups!"); + }); + } + }); + } else { + outputHTML5(404,response,'Y\'a rien ici',"Oups"); + } +}); + +server.listen(80); \ No newline at end of file diff --git a/b3-dev/node/eval/package.json b/b3-dev/node/eval/package.json new file mode 100644 index 0000000..4057390 --- /dev/null +++ b/b3-dev/node/eval/package.json @@ -0,0 +1,18 @@ +{ + "type": "module", + "name": "eval", + "version": "1.0.0", + "description": "", + "main": "front.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "email-validator": "^2.0.4", + "mariadb": "^3.0.0", + "md5": "^2.3.0", + "node-fetch": "^3.2.6" + } +} diff --git a/b3-dev/node/eval/sujet.md b/b3-dev/node/eval/sujet.md new file mode 100644 index 0000000..8b0a5b3 --- /dev/null +++ b/b3-dev/node/eval/sujet.md @@ -0,0 +1,11 @@ +Bonjour à tous, + +Voici le sujet pour ce matin : +https://forms.gle/DMdrnCPvyN9WYJMr8 + +J'essaye de rester disponible sur teams si vous avez des questions. + +Je ferme la possiblité de soumettre des réponse à 12h30. +Commencer donc à relire / préparer vos zips à 12h15. + +Bon courage ! \ No newline at end of file diff --git a/b3-dev/node/eval/users.sql b/b3-dev/node/eval/users.sql new file mode 100644 index 0000000..f4a0714 --- /dev/null +++ b/b3-dev/node/eval/users.sql @@ -0,0 +1,46 @@ +-- phpMyAdmin SQL Dump +-- version 5.1.1 +-- https://www.phpmyadmin.net/ +-- +-- Hôte : 127.0.0.1 +-- Généré le : mer. 22 juin 2022 à 15:33 +-- Version du serveur : 10.4.19-MariaDB +-- Version de PHP : 7.4.20 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- Base de données : `eval_bdd` +-- + +-- -------------------------------------------------------- + +-- +-- Structure de la table `users` +-- + +DROP TABLE IF EXISTS `users`; +CREATE TABLE `users` ( + `courriel` varchar(255) NOT NULL, + `mot_de_passe` varchar(32) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Déchargement des données de la table `users` +-- +TRUNCATE `users`; +INSERT INTO `users` (`courriel`, `mot_de_passe`) VALUES +('test@test.Fr', MD5('be1b4')); +COMMIT; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/b3-dev/node/session3/config.json/config.local.json b/b3-dev/node/session3/config.json/config.local.json new file mode 100644 index 0000000..f1f8470 --- /dev/null +++ b/b3-dev/node/session3/config.json/config.local.json @@ -0,0 +1,24 @@ +{ + "development": { + "config_id": "development", + "app_name": "conf-test", + "app_desc": "An app to test environnement variables", + "node_port": 3000, + "json_indentation": 4, + "database": "nodesandbox_env-dev" + }, + "testing": { + "config_id": "testing", + "database": "nodesandbox_env-tst" + }, + "staging": { + "config_id": "staging - local", + "node_port": 8080, + "database": "nodesandbox_env-stage" + }, + "production": { + "config_id": "production", + "node_port": 8080, + "database": "nodesandbox_env" + } +} \ No newline at end of file diff --git a/b3-dev/node/session3/config.json/package.json b/b3-dev/node/session3/config.json/package.json new file mode 100644 index 0000000..4ecb25a --- /dev/null +++ b/b3-dev/node/session3/config.json/package.json @@ -0,0 +1,12 @@ +{ + "name": "jsonconfig", + "version": "1.0.0", + "description": "simple js on config test", + "main": "server.js", + "scripts": { + "start": "node server.js production users=5", + "dev" : "nodemon server.js development" + }, + "author": "", + "license": "ISC" +}