Commit 2201e360ff31d4c08f1449cb3dafcdaf0d270a90

Authored by Geoffrey PREUD'HOMME
1 parent bc6e4c53

Le login se fait désormais de manière encryptée

Makefile 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +config/ci_com_pub.pem: config/ci_com.pem
  2 + openssl rsa -pubout -in $< -out $@
  3 + chmod 777 $@
  4 +
  5 +config/ci_com.pem:
  6 + openssl genrsa -out $@ 1024
  7 + chmod 700 $@
app/controllers/decrypt.js 0 → 100644
@@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
  1 +var ursa = require('ursa');
  2 +var fs = require('fs');
  3 +
  4 +var decrypt = {};
  5 +
  6 +decrypt.decrypter = false;
  7 +
  8 +decrypt.whenOk = function (cb) {
  9 + if (this.encrypter) {
  10 + cb();
  11 + } else {
  12 + this.prepare(cb);
  13 + }
  14 +};
  15 +
  16 +decrypt.prepare = function (cb) {
  17 + fs.readFile('config/ci_com.pem', function(err, data) {
  18 + if (err) {
  19 + throw err;
  20 + }
  21 + this.decrypter = ursa.createPrivateKey(data);
  22 + cb();
  23 + });
  24 +};
  25 +
  26 +decrypt.preload = function(cb) {
  27 + this.whenOk(cb);
  28 +};
  29 +
  30 +decrypt.decrypt = function (string, cb) {
  31 + this.whenOk(function() {
  32 + cb(this.decrypter.decrypt(string, 'base64', 'utf8', ursa.RSA_PKCS1_PADDING));
  33 + });
  34 +};
  35 +
  36 +module.exports = decrypt;
app/controllers/sessions.js
@@ -115,4 +115,4 @@ sessions.open = function (data, cb) { @@ -115,4 +115,4 @@ sessions.open = function (data, cb) {
115 }); 115 });
116 } 116 }
117 117
118 -module.exports = sessions;  
119 \ No newline at end of file 118 \ No newline at end of file
  119 +module.exports = sessions;
1 var membres = require('../controllers/membres'); 1 var membres = require('../controllers/membres');
2 var sessions = require('../controllers/sessions'); 2 var sessions = require('../controllers/sessions');
  3 +var decrypt = require('../controllers/decrypt');
3 var express = require('express'); 4 var express = require('express');
4 5
5 -var api = express() 6 +var api = express();
6 7
7 // Sessions 8 // Sessions
8 api.get('/session', function (req, res) { // Informations sur la session 9 api.get('/session', function (req, res) { // Informations sur la session
9 - if (req.cookies && req.cookies.session) {  
10 - sessions.use(req.cookies.session, function (err) {  
11 - if (err) {  
12 - res.send(err)  
13 - } else {  
14 - res.send(sessions.cur)  
15 - }  
16 - })  
17 - // TODO si pas bon : res.clearCookie('session')  
18 - } else {  
19 - res.send('missing');  
20 - } 10 + if (req.cookies && req.cookies.session) {
  11 + sessions.use(req.cookies.session, function (err) {
  12 + if (err) {
  13 + res.send(err);
  14 + } else {
  15 + res.send(sessions.cur);
  16 + }
  17 + });
  18 + // TODO si pas bon : res.clearCookie('session')
  19 + } else {
  20 + res.send('missing');
  21 + }
21 }); 22 });
22 23
23 api.post('/session', function (req, res) { // Se connecter 24 api.post('/session', function (req, res) { // Se connecter
24 - sessions.open(req.body, function (err) {  
25 - if (err) {  
26 - res.send(err)  
27 - } else {  
28 - res.cookie('session', sessions.cur._id);  
29 - res.send(sessions.cur)  
30 - }  
31 - })  
32 -}) 25 + decrypt.decrypt(req.body[0], function (data) {
  26 + sessions.open(JSON.parse(data), function (err) {
  27 + if (err) {
  28 + res.send(err);
  29 + } else {
  30 + res.cookie('session', sessions.cur._id);
  31 + res.send(sessions.cur);
  32 + }
  33 + });
  34 + });
  35 +});
33 36
34 api.delete('/session', function (req, res) { // Se déconnecter 37 api.delete('/session', function (req, res) { // Se déconnecter
35 - if (req.cookies.session) {  
36 - sessions.delete(req.cookies.session, function () {  
37 - res.clearCookie('session');  
38 - res.end()  
39 - })  
40 - } else {  
41 - res.send('missing')  
42 - }  
43 -}) 38 + if (req.cookies.session) {
  39 + sessions.delete(req.cookies.session, function () {
  40 + res.clearCookie('session');
  41 + res.end();
  42 + });
  43 + } else {
  44 + res.send('missing');
  45 + }
  46 +});
44 47
45 ifPermission = function (req, res, perm, cb) { 48 ifPermission = function (req, res, perm, cb) {
46 - sessions.use(req.cookies.session, function (err) {  
47 - if (err) {  
48 - res.status(403).end()  
49 - } else {  
50 - if (sessions.cur[perm]) {  
51 - cb()  
52 - } else {  
53 - res.status(403).end()  
54 - }  
55 - }  
56 - })  
57 -} 49 + sessions.use(req.cookies.session, function (err) {
  50 + if (err) {
  51 + res.status(403).end();
  52 + } else {
  53 + if (sessions.cur[perm]) {
  54 + cb();
  55 + } else {
  56 + res.status(403).end();
  57 + }
  58 + }
  59 + });
  60 +};
58 61
59 62
60 // Membres 63 // Membres
61 api.get('/membres', function (req, res) { // Liste des membres 64 api.get('/membres', function (req, res) { // Liste des membres
62 - membres.list(function (err, membres) {  
63 - if (err)  
64 - res.send(err);  
65 - res.json(membres);  
66 - }); 65 + membres.list(function (err, membres) {
  66 + if (err)
  67 + res.send(err);
  68 + res.json(membres);
  69 + });
67 }); 70 });
68 71
69 api.post('/membres', function (req, res) { // Ajout d'un membre 72 api.post('/membres', function (req, res) { // Ajout d'un membre
70 - ifPermission(req, res, 'canAddMembre', function () {  
71 - membres.add(req.body, function (err, membre) {  
72 - if (err)  
73 - res.send(err);  
74 - membres.list(function (err, membres) {  
75 - if (err)  
76 - res.send(err);  
77 - res.json(membres);  
78 - });  
79 - });  
80 - }) 73 + ifPermission(req, res, 'canAddMembre', function () {
  74 + membres.add(req.body, function (err, membre) {
  75 + if (err)
  76 + res.send(err);
  77 + membres.list(function (err, membres) {
  78 + if (err)
  79 + res.send(err);
  80 + res.json(membres);
  81 + });
  82 + });
  83 + });
81 }); 84 });
82 85
83 api.delete('/membres/:membre_id', function (req, res) { // Supression d'un membre 86 api.delete('/membres/:membre_id', function (req, res) { // Supression d'un membre
84 - ifPermission(req, res, 'canDelMembre', function () {  
85 - membres.remove(req.params.membre_id, function (err, membre) {  
86 - if (err)  
87 - res.send(err);  
88 - membres.list(function (err, membres) {  
89 - if (err)  
90 - res.send(err);  
91 - res.json(membres);  
92 - });  
93 - });  
94 - })  
95 -}) 87 + ifPermission(req, res, 'canDelMembre', function () {
  88 + membres.remove(req.params.membre_id, function (err, membre) {
  89 + if (err)
  90 + res.send(err);
  91 + membres.list(function (err, membres) {
  92 + if (err)
  93 + res.send(err);
  94 + res.json(membres);
  95 + });
  96 + });
  97 + });
  98 +});
96 99
97 -module.exports = api;  
98 \ No newline at end of file 100 \ No newline at end of file
  101 +module.exports = api;
@@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
5 "font-awesome": "latest", 5 "font-awesome": "latest",
6 "angular": "latest", 6 "angular": "latest",
7 "angular-route": "latest", 7 "angular-route": "latest",
8 - "bootswatch-dist": "3.3.2-cerulean" 8 + "bootswatch-dist": "3.3.2-cerulean",
  9 + "jsencrypt": "~2.1.0"
9 } 10 }
10 } 11 }
@@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
9 "method-override": "^2.3.1", 9 "method-override": "^2.3.1",
10 "mongoose": "^3.8.25", 10 "mongoose": "^3.8.25",
11 "morgan": "^1.5.1", 11 "morgan": "^1.5.1",
12 - "node-line-reader": "0.0.2" 12 + "node-line-reader": "0.0.2",
  13 + "ursa": "^0.8.4"
13 } 14 }
14 } 15 }
public/com/ci_com.pem 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +Même pas en rêve !
public/com/ci_com_priv.pem 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +ci_com.pem
0 \ No newline at end of file 2 \ No newline at end of file
public/com/ci_com_pub.pem 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +../../config/ci_com_pub.pem
0 \ No newline at end of file 2 \ No newline at end of file
1 -angular.module('ciApp', ['ngRoute', 'appRoutes', 'SessionsServ', 'SessionsCtrl', 'ConnectCtrl', 'MembreCtrl']);  
2 \ No newline at end of file 1 \ No newline at end of file
  2 +angular.module('ciApp', ['ngRoute', 'appRoutes', 'EncryptServ', 'SessionsServ', 'SessionsCtrl', 'ConnectCtrl', 'MembreCtrl']);
public/js/controllers/ConnectCtrl.js
1 -angular.module('ConnectCtrl', []).controller('ConnectController', ['$scope', 'SessionService',  
2 - function ($scope, SessionService) {  
3 - $scope.connect = {  
4 - connect: function () {  
5 - SessionService.connect($scope.connect.login, $scope.connect.pass)  
6 - }  
7 - }  
8 - }  
9 -]);  
10 \ No newline at end of file 1 \ No newline at end of file
  2 +angular.module('ConnectCtrl', []).controller('ConnectController', ['$scope', 'SessionService', 'EncryptService',
  3 + function ($scope, SessionService, EncryptService) {
  4 + EncryptService.preload(function () {
  5 + return undefined;
  6 + });
  7 + $scope.connect = {
  8 + connect: function () {
  9 + SessionService.connect($scope.connect.login, $scope.connect.pass);
  10 + }
  11 + };
  12 + }
  13 +]);
public/js/services/EncryptServ.js 0 → 100644
@@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
  1 +angular.module('EncryptServ', []).service('EncryptService', ['$http',
  2 + function ($http) {
  3 + a = {
  4 + encrypter: false,
  5 + whenOk: function (cb) {
  6 + if (this.encrypter) {
  7 + cb();
  8 + } else {
  9 + this.prepare(cb);
  10 + }
  11 + },
  12 + prepare: function (cb) {
  13 + $http.get('/com/ci_com_pub.pem').success(function (key) {
  14 + this.encrypter = new JSEncrypt();
  15 + this.encrypter.setPublicKey(key);
  16 + cb();
  17 + });
  18 + },
  19 + preload: function(cb) {
  20 + this.whenOk(cb);
  21 + },
  22 + encrypt: function (string, cb) {
  23 + this.whenOk(function() {
  24 + cb(this.encrypter.encrypt(string));
  25 + });
  26 + }
  27 + };
  28 + return a;
  29 + }
  30 +]);
public/js/services/SessionServ.js
1 -angular.module('SessionsServ', []).service('SessionService', ['$http',  
2 - function ($http) {  
3 - a = {  
4 - cur: false,  
5 - status: 0,  
6 - changeHandlers: [],  
7 - onChange: function (fun) {  
8 - this.changeHandlers.push(fun)  
9 - },  
10 - triggerChange: function () {  
11 - for (fun in this.changeHandlers) {  
12 - this.changeHandlers[fun]()  
13 - }  
14 - },  
15 - updateSessionInfos: function (data) {  
16 - console.log("Connection:", data)  
17 - if (typeof data === 'object') {  
18 - this.cur = data  
19 - } else {  
20 - this.cur = false  
21 - }  
22 - this.triggerChange()  
23 - },  
24 - get: function (cb) { // Fetch infos if needed  
25 - if (status == 0) {  
26 - this.status = 1 // Fetching  
27 - _this = this  
28 - // TODO Verify if cookies to prevent uneeded request  
29 - $http.get('/api/session').success(function (body) {  
30 - _this.updateSessionInfos(body)  
31 - if (cb) {  
32 - if (this.logged) {  
33 - cb(null)  
34 - } else {  
35 - cb(body)  
36 - }  
37 - }  
38 - })  
39 - } else {  
40 - console.warn("Unnecessary get() call")  
41 - }  
42 - },  
43 - connect: function (login, pass, cb) {  
44 - _this = this  
45 - $http.post('/api/session', {  
46 - login: login,  
47 - pass: pass  
48 - }).success(function (body) {  
49 - _this.updateSessionInfos(body)  
50 - if (cb) {  
51 - if (this.logged) {  
52 - cb(null)  
53 - } else {  
54 - cb(body)  
55 - }  
56 - }  
57 - })  
58 - },  
59 - disconnect: function () {  
60 - this.updateSessionInfos(false)  
61 - $http.delete('/api/session') 1 +angular.module('SessionsServ', []).service('SessionService', ['$http', 'EncryptService',
  2 + function ($http, EncryptService) {
  3 + a = {
  4 + cur: false,
  5 + status: 0,
  6 + changeHandlers: [],
  7 + onChange: function (fun) {
  8 + this.changeHandlers.push(fun);
  9 + },
  10 + triggerChange: function () {
  11 + for (var fun in this.changeHandlers) {
  12 + this.changeHandlers[fun]();
  13 + }
  14 + },
  15 + updateSessionInfos: function (data) {
  16 + console.log("Connection:", data);
  17 + if (typeof data === 'object') {
  18 + this.cur = data;
  19 + } else {
  20 + this.cur = false;
  21 + }
  22 + this.triggerChange();
  23 + },
  24 + get: function (cb) { // Fetch infos if needed
  25 + if (status === 0) {
  26 + this.status = 1; // Fetching
  27 + _this = this;
  28 + // TODO Verify if cookies to prevent uneeded request
  29 + $http.get('/api/session').success(function (body) {
  30 + _this.updateSessionInfos(body);
  31 + if (cb) {
  32 + if (this.logged) {
  33 + cb(null);
  34 + } else {
  35 + cb(body);
  36 + }
62 } 37 }
  38 + });
  39 + } else {
  40 + console.warn("Unnecessary get() call");
63 } 41 }
64 - a.get()  
65 - return a  
66 - }  
67 -])  
68 \ No newline at end of file 42 \ No newline at end of file
  43 + },
  44 + connect: function (login, pass, cb) {
  45 + _this = this;
  46 + data = JSON.stringify({
  47 + login: login,
  48 + pass: pass
  49 + });
  50 + EncryptService.encrypt(data, function (dataCrypt) {
  51 + $http.post('/api/session', [dataCrypt]).success(function (body) {
  52 + _this.updateSessionInfos(body);
  53 + if (cb) {
  54 + if (this.logged) {
  55 + cb(null);
  56 + } else {
  57 + cb(body);
  58 + }
  59 + }
  60 + });
  61 + });
  62 + },
  63 + disconnect: function () {
  64 + this.updateSessionInfos(false);
  65 + $http.delete('/api/session');
  66 + }
  67 + };
  68 + a.get();
  69 + return a;
  70 + }
  71 +]);
public/views/connect.html
1 <div class="container"> 1 <div class="container">
2 <h1>Se connecter</h1> 2 <h1>Se connecter</h1>
3 - <div class="alert alert-warning" role="alert"><strong>Faites attention !</strong> Ce site internet est encore en développement, les connexions ne sont pas sécurisées.<br/>  
4 - Soyez sûr d'être sur un réseau sécurisé tel que celui de Polytech ou de votre box internet avant d'entrer votre mot de passe.</div>  
5 <form> 3 <form>
6 <div class="form-group"> 4 <div class="form-group">
7 <label for="login">Identifiant</label> 5 <label for="login">Identifiant</label>
@@ -13,4 +11,4 @@ @@ -13,4 +11,4 @@
13 </div> 11 </div>
14 <button type="submit" class="btn btn-default" ng-click="connect.connect()">Se connecter</button> 12 <button type="submit" class="btn btn-default" ng-click="connect.connect()">Se connecter</button>
15 </form> 13 </form>
16 -</div>  
17 \ No newline at end of file 14 \ No newline at end of file
  15 +</div>
public/views/index.html
@@ -11,7 +11,9 @@ @@ -11,7 +11,9 @@
11 <script src="libs/angular/angular.min.js"></script> 11 <script src="libs/angular/angular.min.js"></script>
12 <script src="libs/angular-route/angular-route.min.js"></script> 12 <script src="libs/angular-route/angular-route.min.js"></script>
13 <script src="libs/angular-bootstrap/ui-bootstrap.min.js"></script> 13 <script src="libs/angular-bootstrap/ui-bootstrap.min.js"></script>
  14 + <script src="libs/jsencrypt/bin/jsencrypt.min.js"></script>
14 <script src="js/controllers/MembreCtrl.js"></script> 15 <script src="js/controllers/MembreCtrl.js"></script>
  16 + <script src="js/services/EncryptServ.js"></script>
15 <script src="js/services/SessionServ.js"></script> 17 <script src="js/services/SessionServ.js"></script>
16 <script src="js/controllers/SessionCtrl.js"></script> 18 <script src="js/controllers/SessionCtrl.js"></script>
17 <script src="js/controllers/ConnectCtrl.js"></script> 19 <script src="js/controllers/ConnectCtrl.js"></script>
@@ -41,4 +43,4 @@ @@ -41,4 +43,4 @@
41 <div ng-view></div> 43 <div ng-view></div>
42 </div> 44 </div>
43 </body> 45 </body>
44 -</html>  
45 \ No newline at end of file 46 \ No newline at end of file
  47 +</html>