Skip to content
Snippets Groups Projects
Commit bea69fad authored by Wilson JALLET's avatar Wilson JALLET :money_with_wings:
Browse files

Merge branch 'master' of gitlab.binets.fr:br/sigma-backend

parents 1deda052 d012419d
No related branches found
No related tags found
No related merge requests found
Contribuer
===
## Description et actualite des branches
### stable
- déploiement de l'API pour les développeurs du front
### master
- une branche où on fait des petits commits pour merge dans stable
### schema_kadabra
- la branche sur laquelle kadabra commitait sa wish-list, maintenant c'est fait (on devrait supprimer cette branche d'ailleurs)
### resolver_dev
- branche sur laquelle akka vodol fais tout mon travail. Comme ça, il peut faire d'éventuelles modifications du schéma sans faire chier les autres, et ensuite on valide ensemble pour merge
### orienteobjet
- branche sur laquelle hawkspar développait la version "orienté objet" de ldap_data.js
## Contact
le BR 2016
...@@ -106,6 +106,15 @@ Il faut se référer à la documentation de Knex.js pour comprendre comment écr ...@@ -106,6 +106,15 @@ Il faut se référer à la documentation de Knex.js pour comprendre comment écr
On peut facilement explorer et modifier des éléments du LDAP de l'école depuis le réseau de l'X avec [JXplorer](http://jxplorer.org/) en entrant `frankiz` dans nouvelle connexion et en allant dans `net`. On peut facilement explorer et modifier des éléments du LDAP de l'école depuis le réseau de l'X avec [JXplorer](http://jxplorer.org/) en entrant `frankiz` dans nouvelle connexion et en allant dans `net`.
### Accéder à la BDD de sigma propre
Pour accéder à la "vraie" BDD, sur roued (le serveur qui héberge sigma), il faut
* se connecter dessus en `ssh roued`
* passer en `sudo`
* faire un `su postgres` pour se faire passer pour l'utilisateur unix postgres
* se connecter à la BDD via la commande `psql`
* faire les requetes en SQL par l'interface de postgreSQL.
## Scripts ## Scripts
Les scripts sont des instructions en ligne de commande que l'on peut faire tourner avec la commande `npm run`. Ce sont des raccourcis pour gagner du temps sur des opérations un peu longues. Ils sont définis dans [`package.json`](../package.json). Les scripts sont des instructions en ligne de commande que l'on peut faire tourner avec la commande `npm run`. Ce sont des raccourcis pour gagner du temps sur des opérations un peu longues. Ils sont définis dans [`package.json`](../package.json).
...@@ -146,4 +155,4 @@ qui fait appel au script `eslint src/` défini dans le [`package.json`](../packa ...@@ -146,4 +155,4 @@ qui fait appel au script `eslint src/` défini dans le [`package.json`](../packa
Sinon, si vous utilisez Atom ou Visual Studio Code pour éditer votre code, il existe des plugins qui font tourner ESLint en _live_ sur le code et vérifient que tout est en ordre. Sinon, si vous utilisez Atom ou Visual Studio Code pour éditer votre code, il existe des plugins qui font tourner ESLint en _live_ sur le code et vérifient que tout est en ordre.
Pour mieux comprendre ESLint, référez-vous à la [doc](https://eslint.org/docs/user-guide/getting-started). Pour mieux comprendre ESLint, référez-vous à la [doc](https://eslint.org/docs/user-guide/getting-started).
\ No newline at end of file
...@@ -20,15 +20,15 @@ let port = process.env.PORT || 3000; ...@@ -20,15 +20,15 @@ let port = process.env.PORT || 3000;
*/ */
router.get('/', function (req, res) { router.get('/', function (req, res) {
console.log('Redirecting to admin page...'); console.log('Connecting to ' + req.url);
console.log('Trying to go to admin page...');
res.redirect('/admin'); res.redirect('/admin');
}); });
router.get('/login', function (req, res) { router.get('/login', function (req, res) {
console.log('Connecting to ' + req.url); console.log('Connecting to ' + req.url);
req.flash('failureFlash', 'Invalid username or password.');
res.render('login', { title: 'Login', port: port, res.render('login', { title: 'Login', port: port,
errorMessage: req.flash('error') }); errorMessage: req.flash('error') }); //lets pug render src/views/login.pug with specified attributes
}); });
router.get('/admin', router.get('/admin',
...@@ -36,20 +36,22 @@ router.get('/admin', ...@@ -36,20 +36,22 @@ router.get('/admin',
function (req, res) { function (req, res) {
console.log('Connecting to ' + req.url); console.log('Connecting to ' + req.url);
let userName; let userName;
/* // Une erreur a ce stade peut etre triggered si req.user n'existe pas
* On ne veut pas déclencer d'erreur 500 si on ne peut pas lire l'utilisateur // mais pour autant on est assures que la personne est bien authentifiee
* La personne n'est peut-être pas connectée, mais cela doit être géré autrement // donc on laisse passer sans déclencher d'erreur 500
*/
try { try {
let user = req.session.passport.user; let user = req.user;
console.log('Welcome,',user.cn); //let user = req.user;
userName = user.cn; console.log('Welcome,',user.uid);
userName = user.uid;
} catch (err) { } catch (err) {
console.log("Warning: in admin_router router.get('/admin')");
console.log(err.message); console.log(err.message);
userName = "No one"; userName = "No one";
} }
res.render('home', { title: 'Home', port: port, userName: userName }); res.render('home', { title: 'Home', port: port, userName: userName });
}); }
);
router.post('/login', router.post('/login',
passport.authenticate('ldapauth', { passport.authenticate('ldapauth', {
......
...@@ -83,9 +83,9 @@ const RootQuery = ` ...@@ -83,9 +83,9 @@ const RootQuery = `
sport: String, sport: String,
phone: String, phone: String,
mail: String, mail: String,
adress: String, address: String,
ip: String ip: String
): [String] ): [User!]
} }
`; `;
......
...@@ -151,7 +151,7 @@ const Message = ` ...@@ -151,7 +151,7 @@ const Message = `
views: Int # TODO mettre un commentaire pour expliquer views: Int # TODO mettre un commentaire pour expliquer
# Si cette Announcement annonce un événement, référence le Event. Sinon null. # Si cette Announcement annonce un événement, référence le Event. Sinon null.
forEvent : Event forEvent: Event
} }
# Événements organisés par un ou plusieurs groupes. # Événements organisés par un ou plusieurs groupes.
...@@ -174,7 +174,7 @@ const Message = ` ...@@ -174,7 +174,7 @@ const Message = `
participatingUsers: [User] participatingUsers: [User]
# Si cet Event a été annoncé par un Announcement, le référence. Sinon null. # Si cet Event a été annoncé par un Announcement, le référence. Sinon null.
asAnnouncement : Announcement forAnnouncement: Announcement
} }
# Post interne d'un membre sur la page interne de son groupe # Post interne d'un membre sur la page interne de son groupe
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
import express from 'express'; import express from 'express';
import schema from './graphql/schema'; import schema from './graphql/schema';
import { express as graphqlVoyager } from 'graphql-voyager/middleware'; import { express as graphqlVoyager } from 'graphql-voyager/middleware';
import { graphqlExpress, graphiqlExpress } from 'graphql-server-express'; import { graphqlExpress, graphiqlExpress } from 'apollo-server-express'; // new name of 'graphql-server-express'. cf npmjs.com
import flash from 'connect-flash'; import flash from 'connect-flash';
import { ensureLoggedIn } from 'connect-ensure-login'; import { ensureLoggedIn } from 'connect-ensure-login';
import passport from 'passport'; import passport from 'passport';
...@@ -22,15 +22,29 @@ import path from 'path'; ...@@ -22,15 +22,29 @@ import path from 'path';
import cors from 'cors'; import cors from 'cors';
const server = express(); const server = express();
// on sait pas a quoi ca sert mais il parait que c'est utile
server.use(bodyParser.json()); // Parse incoming HTTP request bodies, available under the req.body property
server.use(bodyParser.urlencoded({ // cf www.npmjs.com/package/body-parser
extended: true server.use(bodyParser.json()); //parses bodies of media type "application/json"
server.use(bodyParser.urlencoded({ //parses bodies of media type "application/x-www-form-urlencoded"
extended: true //use qs library (quoi que ca veuille dire o.O)
})); }));
/** /**
* @description Configuration authentification * @description Configuration de l'authentification
* @author guillaume.wang * @author guillaume.wang
*
* on a besoin d'authentification pour 2 trucs :
* - l'acces a l'interface admin (admin_view) du back, definie dans admin_router.js
* - le contexte graphQL
*
* serializeUser et deserializeUser: passport s'attend a ce qu'on ait besoin d'avoir req.user disponible partout dans notre code
* En gros l'idee de passport c'est: serializeUser permet d'obtenir une cle identifiant chaque user
* et deserializeUser prend cette cle, fait une requete vers une BDD de users et met dans l'objet JS req.user toutes les infos issues de la BDD
* Cette repartition permet de ne stocker dans la session (i.e. en memoire sur le serveur) que la cle des utilisateurs connectes et de ne "charger en memoire" toutes les infos de la BDD que lorsque necessaire
* cf https://stackoverflow.com/questions/27637609/understanding-passport-serialize-deserialize#27637668
*
* Mais en fait dans notre cas c'est graphql qui communique avec la BDD, donc on s'en fiche! On peut se contenter de dire a serializeUser et deserializeUser de ne s'occuper que du champ uid)
*/ */
let configPath = path.resolve('./', 'ldap_config.json'); let configPath = path.resolve('./', 'ldap_config.json');
let config = JSON.parse(fs.readFileSync(configPath, 'utf8')); let config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
...@@ -38,11 +52,24 @@ let config = JSON.parse(fs.readFileSync(configPath, 'utf8')); ...@@ -38,11 +52,24 @@ let config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
passport.use(new LdapStrategy({ passport.use(new LdapStrategy({
server: { server: {
url: config.ldap.server, url: config.ldap.server,
//bindDn: '.............',
//bindCredentials: '..........',
searchBase: config.ldap.searchBase, searchBase: config.ldap.searchBase,
searchFilter: config.ldap.searchFilter searchFilter: config.ldap.searchFilter,
//searchAttributes: ['givenName', 'sn'],
//tlsOptions: '..........',
},
//usernameField: 'username', // Field name where the username is found, defaults to username
//passwordField: 'password', // Field name where the password is found, defaults to password
passReqToCallback: true, // set verify callback to have req as the first argument
function (req, user, done) {
// "verify callback", called after each passport.authenticate(...) when the authentication succeeded
if (user){
//if user exists
}
} }
} })
)); );
// Définit les paramètres de stockage des sessions. // Définit les paramètres de stockage des sessions.
server.use(session({ server.use(session({
...@@ -53,18 +80,22 @@ server.use(session({ ...@@ -53,18 +80,22 @@ server.use(session({
server.use(passport.initialize()); server.use(passport.initialize());
server.use(passport.session()); server.use(passport.session());
//toujours bon a savoir pour faire des tests:
//The result of the serializeUser method is attached to the session as req.session.passport.user
passport.serializeUser(function (user, done) { passport.serializeUser(function (user, done) {
done(null, user); done(null, user.uid);
}); });
passport.deserializeUser(function (user, done) { //The first argument of deserializeUser corresponds to the key of the user object that was given to the done function in serializeUser
done(null, user); //The fetched object is attached to the request object as req.user (available in all subsequent middleware)
passport.deserializeUser(function (userUid, done) {
done(null, { uid: userUid });
}); });
/* fin de Configuration de l'authentification */
/** // cache le fait que l'application tourne sous Express dans le header HTTP.
* @description Cache le fait que l'application tourne sous Express dans le header HTTP.
*/
server.disable('x-powered-by'); server.disable('x-powered-by');
// setting up view engine for pug // setting up view engine for pug
console.log("Running at",__dirname); console.log("Running at",__dirname);
let viewpath = path.resolve(__dirname,'views'); let viewpath = path.resolve(__dirname,'views');
...@@ -74,6 +105,7 @@ server.set('view engine', 'pug'); ...@@ -74,6 +105,7 @@ server.set('view engine', 'pug');
// favicon: capital sigma symbol // favicon: capital sigma symbol
server.use(favicon(path.resolve('./','assets','favicon.ico'))); server.use(favicon(path.resolve('./','assets','favicon.ico')));
// specifies path to static assets
server.use('/assets',express.static(path.resolve('./','assets'))); server.use('/assets',express.static(path.resolve('./','assets')));
// Morgan is middleware for logging requests // Morgan is middleware for logging requests
...@@ -81,44 +113,53 @@ server.use(morgan('dev')); ...@@ -81,44 +113,53 @@ server.use(morgan('dev'));
const defaultUser = require('./../ldap_connexion_config.json'); const defaultUser = require('./../ldap_connexion_config.json');
/** // Options de configuration pour le _middleware_ `cors`.
* @desc Options de configuration pour le _middleware_ `cors`. // CORS = Cross Origin Resource Sharing
*/
const corsOptions = { const corsOptions = {
origin: 'http://localhost:8888', origin: 'http://localhost:8888', // Configures the Access-Control-Allow-Origin CORS header. i.e. specifies that sigma-back wants to make resources accessible to this site (and this site only)
credentials: true // <-- REQUIRED backend setting credentials: true // Configures the Access-Control-Allow-Credentials CORS header. i.e. allows cookies to be included on cross-origin requests
}; };
server.use(cors(corsOptions)); server.use(cors(corsOptions));
// Charge le middleware express pour GraphQL // Charge le middleware express pour GraphQL
server.use('/graphql', bodyParser.json(), server.use('/graphql', bodyParser.json(),
graphqlExpress(req => { graphqlExpress(req => {
// vary the options *on a per-request basis*
// (options are passed by using req object as argument)
let uid; let uid;
let password; let password;
try { try {
uid = req.session.passport.user.uid; uid = req.user.uid;
password = "mythe"; password = "mythe";
} catch (err) { } catch (err) {
uid = defaultUser.dn.split("=")[1].split(",")[0]; uid = defaultUser.dn.split("=")[1].split(",")[0];
password = defaultUser.passwd; password = defaultUser.passwd;
} }
// console.log("Accessing GraphQL as:",uid); // console.log("Accessing GraphQL as: ",uid);
return { return {
schema : schema, schema : schema,
context : {user : {uid : uid, password : password}} context: { user: { uid: uid, password: password } } // accessible in every single resolver as the third argument
}; };
})); })
);
// GraphiQL est une console interactive pour faire des requêtes au schéma GraphQL // GraphiQL est une console interactive pour faire des requêtes GraphQL à la BDD
server.use('/graphiql', /*ensureLoggedIn('/login'),*/ graphiqlExpress({endpointURL: '/graphql'})); server.use('/graphiql',
/*ensureLoggedIn('/login'),*/
graphiqlExpress({endpointURL: '/graphql'})
);
// GraphQL voyager // GraphQL voyager affiche une représentation sous forme de graphe du schema GraphQL
server.use('/voyager', graphqlVoyager({ endpointUrl: '/graphql' })); server.use('/voyager',
/*ensureLoggedIn('/login'),*/
graphqlVoyager({ endpointUrl: '/graphql' })
);
// connect-flash is middleware for flashing messages // connect-flash is middleware for flashing messages
// used in sigma-back's admin interface (admin_view)
server.use(flash()); server.use(flash());
export default server; export default server;
...@@ -15,8 +15,7 @@ block content ...@@ -15,8 +15,7 @@ block content
button.form-control(type="submit",class="button") Recherche/<em>Search</em> button.form-control(type="submit",class="button") Recherche/<em>Search</em>
| |
h2 GraphiQL and Voyager h2 GraphiQL and Voyager
p GraphiQL is an interactive environment to make GraphQL p GraphiQL is an interactive environment to make GraphQL requests to the database.
| requests to the database.
p GraphQL Voyager is an application that displays the GraphQL schema as an actual graph. p GraphQL Voyager is an application that displays the GraphQL schema as an actual graph.
a(class="button button-small",href="/graphiql") GraphiQL a(class="button button-small",href="/graphiql") GraphiQL
a(class="button button-small",href="/voyager") Voyager a(class="button button-small",href="/voyager") Voyager
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment