diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/.gitignore b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/servicemicrobloggr.png b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/doc/servicemicrobloggr.png similarity index 100% rename from cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/servicemicrobloggr.png rename to cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/doc/servicemicrobloggr.png diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/docker-compose.yml b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/docker-compose.yml new file mode 100644 index 0000000..f06faff --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/docker-compose.yml @@ -0,0 +1,14 @@ +version: '2' +services: + gateway: + build: + context: containers/gateway + ports: + - 8080:80 + + home_page: + build: + context: containers/home_page + login_page: + build: + context: containers/login_page diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/gateway/Dockerfile b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/gateway/Dockerfile new file mode 100644 index 0000000..997772f --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/gateway/Dockerfile @@ -0,0 +1,8 @@ +FROM alpine:3.2 + +RUN apk add --no-cache nginx +COPY microbloggr.conf /etc/nginx/microbloggr.conf + +RUN mkdir -p /var/run/nginx + +CMD ["nginx", "-c", "/etc/nginx/microbloggr.conf"] diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/gateway/microbloggr.conf b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/gateway/microbloggr.conf new file mode 100644 index 0000000..f289811 --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/gateway/microbloggr.conf @@ -0,0 +1,45 @@ +daemon off; + +worker_processes 1; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + + sendfile on; + keepalive_timeout 65; + + gzip on; + + server { + + listen 80; + server_name localhost; + + location / { + proxy_pass http://home_page:8080/; + } + + location /login { + proxy_pass http://login_page:8080/; + } + + # location /profile { + # proxy_pass http://profile_page:8080/; + # } + # + # location /register { + # proxy_pass http://register_page:8080/; + # } + # + # location /statuses { + # proxy_pass http://statuses_page:8080/; + # } + + } + +} diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/.dockerignore b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/.dockerignore new file mode 100644 index 0000000..4e4a23e --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/.dockerignore @@ -0,0 +1 @@ +/app/node_modules diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/Dockerfile b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/Dockerfile new file mode 100644 index 0000000..9cdaec8 --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/Dockerfile @@ -0,0 +1,10 @@ +FROM alpine:3.7 + +RUN apk add --no-cache nodejs + +COPY app /app +WORKDIR /app + +RUN npm install --production + +CMD ["node", "server.js"] diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/app/.gitignore b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/app/.gitignore new file mode 100644 index 0000000..07e6e47 --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/app/.gitignore @@ -0,0 +1 @@ +/node_modules diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/app/package.json b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/app/package.json new file mode 100644 index 0000000..85dc18f --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/app/package.json @@ -0,0 +1,18 @@ +{ + "name": "login_page", + "version": "1.0.0", + "description": "", + "main": "server.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "ejs": "^2.5.7", + "express": "^4.16.2", + "express-session": "^1.15.6", + "request": "^2.83.0", + "request-promise-native": "^1.0.5" + } +} diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/app/server.js b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/app/server.js new file mode 100644 index 0000000..66d6580 --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/app/server.js @@ -0,0 +1,31 @@ +const express = require('express'); +const session = require('express-session'); +const app = express(); + +app.set('view engine', 'ejs'); + +app.use(session({ + secret: 'AbsolutlyNotSecret', // Ce secret doit être partagé par tous les microservices *_page + resave: false, + saveUninitialized: true, +})); + +// GET / +// Retourne la page d'accueil de MicroBloggr ou redirige vers la +// page de login si l'utilisateur n'est pas identifié +app.get('/', (req, res) => { + + const sess = req.session; + + // On vérifie si un utilisateur a été associé à la session HTTP + if (req.session.user) { + // Si oui, on affichage la page d'accueil + return res.render('index'); + } else { + // Si non, on redirige l'utilisateur vers la page de login + return res.redirect(301, '/login'); + } + +}); + +app.listen(8080, () => console.log('listening on port 8080')); diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/app/views/index.ejs b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/app/views/index.ejs new file mode 100644 index 0000000..2bb1ef3 --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/home_page/app/views/index.ejs @@ -0,0 +1,9 @@ + + +
+
+ + + + diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/.dockerignore b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/.dockerignore new file mode 100644 index 0000000..4e4a23e --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/.dockerignore @@ -0,0 +1 @@ +/app/node_modules diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/Dockerfile b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/Dockerfile new file mode 100644 index 0000000..9cdaec8 --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/Dockerfile @@ -0,0 +1,10 @@ +FROM alpine:3.7 + +RUN apk add --no-cache nodejs + +COPY app /app +WORKDIR /app + +RUN npm install --production + +CMD ["node", "server.js"] diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/app/.gitignore b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/app/.gitignore new file mode 100644 index 0000000..07e6e47 --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/app/.gitignore @@ -0,0 +1 @@ +/node_modules diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/app/package.json b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/app/package.json new file mode 100644 index 0000000..954d211 --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/app/package.json @@ -0,0 +1,19 @@ +{ + "name": "login_page", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "body-parser": "^1.18.2", + "ejs": "^2.5.7", + "express": "^4.16.2", + "express-session": "^1.15.6", + "request": "^2.83.0", + "request-promise-native": "^1.0.5" + } +} diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/app/server.js b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/app/server.js new file mode 100644 index 0000000..d929560 --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/app/server.js @@ -0,0 +1,91 @@ +const express = require('express'); +const app = express(); +const session = require('express-session'); +const bodyParser = require('body-parser'); +const request = require('request-promise-native'); + +app.set('view engine', 'ejs'); + +app.use(session({ + secret: 'AbsolutlyNotSecret', // Ce secret doit être partagé par tous les microservices *_page + resave: false, + saveUninitialized: true, +})); + +// On utilise le module "body-parser" +// pour faciliter la désérialisation des données +// du formulaire +app.use(bodyParser.urlencoded({extended: false})); + +// GET / +// Affiche la page de login +app.get('/', (req, res) => { + res.render('index', { error: null }); +}); + + +// POST / +// Récupère les données du formulaire de login +app.post('/', (req, res) => { + + const form = req.body; + + // Si le formulaire ne contient pas les données attendues + // on renvoie un code HTTP 400 pour indiquer une requête invalide. + if(!form.username || !form.password) { + return res.render('index', { error: 'Identifiant ou mot de passe manquant.'}); + } + + // On interroge le microservices "users" + // pour récupérer l'utilisateur associé à l'identifiant + // fourni dans le formulaire + findUserByName(form.username) + .then(user => { + + // Si l'utilisateur n'existe pas, on affiche un message d'erreur + if(!user) { + return res.render('index', { error: 'Identifiant invalide !'}); + } + + // Si le mot de passe de l'utilisateur correspond à celui enregistré sur le + // microservice "users", on attache l'identifiant de l'utilisateur à la session + // HTTP puis on le redirige sur la page d'accueil + if(user.password === form.password) { + req.session.user = user; + return res.redirect(302, '/'); + } else { + // Sinon, on affiche un message d'erreur + return res.render('index', { error: 'Mot de passe invalide !'}); + } + + }) + .catch(err => { + // Une erreur s'est produite en essayant de contacter le microservices "users" + // On affiche un message d'erreur à l'utilisateur + return res.render('index', { + error: 'Une erreur s\'est produite pendant le processus d\'authentification.' + }); + }) + ; + +}); + +app.listen(8080, () => console.log('listening on port 8080')); + +// Récupère un utilisateur via son identifiant +// sur le microservice "users" +function findUserByName(username) { + return request({ + uri: `http://users:8080/users/${username}`, + json: true + }) + .catch(err => { + // Si le microservice "users" répond avec un code HTTP 404 + // c'est que l'utilisateur n'existe pas + if (err.response.statusCode === 404) { + return null; + } + throw err; + }) + ; +} diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/app/views/index.ejs b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/app/views/index.ejs new file mode 100644 index 0000000..67efbca --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/login_page/app/views/index.ejs @@ -0,0 +1,19 @@ + + +

Login

+ <% if (error) { %> +

<%= error %>

+ <% } %> +
+
+ + +
+
+ + +
+ +
+ + diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/sessions/.dockerignore b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/sessions/.dockerignore new file mode 100644 index 0000000..4e4a23e --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/sessions/.dockerignore @@ -0,0 +1 @@ +/app/node_modules diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/sessions/Dockerfile b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/sessions/Dockerfile new file mode 100644 index 0000000..9cdaec8 --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/sessions/Dockerfile @@ -0,0 +1,10 @@ +FROM alpine:3.7 + +RUN apk add --no-cache nodejs + +COPY app /app +WORKDIR /app + +RUN npm install --production + +CMD ["node", "server.js"] diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/sessions/app/package.json b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/sessions/app/package.json new file mode 100644 index 0000000..dfb2c2e --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/sessions/app/package.json @@ -0,0 +1,15 @@ +{ + "name": "sessions", + "version": "1.0.0", + "description": "", + "main": "server.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "body-parser": "^1.18.2", + "express": "^4.16.2" + } +} diff --git a/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/sessions/app/server.js b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/sessions/app/server.js new file mode 100644 index 0000000..b19bb11 --- /dev/null +++ b/cesi/architecture_n_tiers/ressources/exercices/ex_microbloggr_solution/services/sessions/app/server.js @@ -0,0 +1,102 @@ +const express = require('express'); +const bodyParser = require('body-parser'); +const app = express(); + +const sessions = {}; +let sessionCounter = 0; + +// On utilise le middleware "body-parser" +// pour désérialiser automatiquement +// les objets JSON potentiellement +// fournis par les requêtes +app.use(bodyParser.json()); + +// GET /sessions +// Permet de récupérer la liste des sessions en cours +app.get('/sessions', (req, res) => { + res.json(sessions); +}); + + +// GET /sessions/:id +// Permet de récupérer une session via son identifiant +app.get('/sessions/:id', (req, res) => { + + // On récupère l'identifiant de session + // depuis l'URL + const sessionId = req.params.id; + + // On vérifie que la session existe. + // Si ce n'est pas le cas, on retourne un code + // HTTP 404 pour indiquer que la ressource + // n'existe pas + if (!sessions.hasOwnProperty(sessionId)) { + return res.status(404).end('Not found.'); + } + + // On retourne la session sérialisée en JSON + return res.json(sessions[sessionId]); + +}) + +// POST /sessions +// Body: {"user": } +// Permet de créer une nouvelle session pour l'utilisateur donné +app.post('/sessions', (req, res) => { + + const payload = req.body; + + // On valide la présence de l'attribut "user" + // sur les données fournies. + // Si il n'est pas présent, on retourne un code HTTP + // 400 pour indiquer que la requête est invalide. + if (!payload.user) { + return res.status(400).end('Bad request.'); + } + + // On créait une nouvelle session + const sess = { + user: payload.user, + id: getSessionId(), + }; + + // On la "stocke" dans notre registre + sessions[session.id] = sess; + + // On retourne la session + // nouvellement créée + res.json(sess); + +}) + + +// DELETE /sessions/:id +// Permet de supprimer une session dans le registre via son identifiant +app.delete('/sessions/:id', (req, res) => { + + // On récupère l'identifiant de session + // depuis l'URL + const sessionId = req.params.id; + + // On vérifie que la session existe. + // Si ce n'est pas le cas, on retourne un code + // HTTP 404 pour indiquer que la ressource + // n'existe pas + if (!sessions.hasOwnProperty(sessionId)) { + return res.status(404).end('Not found.'); + } + + delete sessions[sessionId]; + + // On retourne un code HTTP 204 pour indiquer que l'opération + // s'est déroulée correctement mais qu'aucun "contenu" n'est disponible + return res.status(204); + +}); + + +app.listen(8080, () => console.log('listening on port 8080')); + +function getSessionId() { + return `${Date.now()}-${sessionCounter++}`; +} diff --git a/cesi/architecture_n_tiers/ressources/exercices/exo/ex_2_tiers.zip b/cesi/architecture_n_tiers/ressources/exercices/exo/ex_2_tiers.zip new file mode 100644 index 0000000..9465916 Binary files /dev/null and b/cesi/architecture_n_tiers/ressources/exercices/exo/ex_2_tiers.zip differ diff --git a/cesi/architecture_n_tiers/ressources/exercices/exo/ex_2_tiers_solution.zip b/cesi/architecture_n_tiers/ressources/exercices/exo/ex_2_tiers_solution.zip new file mode 100644 index 0000000..b264f09 Binary files /dev/null and b/cesi/architecture_n_tiers/ressources/exercices/exo/ex_2_tiers_solution.zip differ diff --git a/cesi/architecture_n_tiers/ressources/exercices/exo/ex_microbloggr.zip b/cesi/architecture_n_tiers/ressources/exercices/exo/ex_microbloggr.zip new file mode 100644 index 0000000..81e6160 Binary files /dev/null and b/cesi/architecture_n_tiers/ressources/exercices/exo/ex_microbloggr.zip differ diff --git a/cesi/architecture_n_tiers/ressources/exercices/exo/servicemicrobloggr.png b/cesi/architecture_n_tiers/ressources/exercices/exo/servicemicrobloggr.png new file mode 100644 index 0000000..7672225 Binary files /dev/null and b/cesi/architecture_n_tiers/ressources/exercices/exo/servicemicrobloggr.png differ diff --git a/cesi/architecture_n_tiers/ressources/schemas_slides.epgz b/cesi/architecture_n_tiers/ressources/schemas_slides.epgz index 5439b7d..e5d3b34 100644 Binary files a/cesi/architecture_n_tiers/ressources/schemas_slides.epgz and b/cesi/architecture_n_tiers/ressources/schemas_slides.epgz differ