diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000000000000000000000000000000000..c1f7320a9aea14f3336e13b1e9f5502abcba9745 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,30 @@ +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 diff --git a/README.md b/README.md index 1c5239ddc50d09e5dc82bd8255014609a828e72f..0d02aaf0f4f93f4d64fa743dd0b10c376f7542e4 100644 --- a/README.md +++ b/README.md @@ -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`. +### 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 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 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). \ No newline at end of file +Pour mieux comprendre ESLint, référez-vous à la [doc](https://eslint.org/docs/user-guide/getting-started). diff --git a/src/admin_view/admin_router.js b/src/admin_view/admin_router.js index ad03575f749265935380b3c33cc8c0742b2eb4d7..c9e30ba2657f66c53e97f85b6d11a58cceceedd9 100644 --- a/src/admin_view/admin_router.js +++ b/src/admin_view/admin_router.js @@ -20,15 +20,15 @@ let port = process.env.PORT || 3000; */ 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'); }); router.get('/login', function (req, res) { console.log('Connecting to ' + req.url); - req.flash('failureFlash', 'Invalid username or password.'); 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', @@ -36,20 +36,22 @@ router.get('/admin', function (req, res) { console.log('Connecting to ' + req.url); let userName; - /* - * On ne veut pas déclencer d'erreur 500 si on ne peut pas lire l'utilisateur - * La personne n'est peut-être pas connectée, mais cela doit être géré autrement - */ + // Une erreur a ce stade peut etre triggered si req.user n'existe pas + // mais pour autant on est assures que la personne est bien authentifiee + // donc on laisse passer sans déclencher d'erreur 500 try { - let user = req.session.passport.user; - console.log('Welcome,',user.cn); - userName = user.cn; + let user = req.user; + //let user = req.user; + console.log('Welcome,',user.uid); + userName = user.uid; } catch (err) { + console.log("Warning: in admin_router router.get('/admin')"); console.log(err.message); userName = "No one"; } res.render('home', { title: 'Home', port: port, userName: userName }); - }); + } +); router.post('/login', passport.authenticate('ldapauth', { diff --git a/src/graphql/typeDefs/actions_wish_list.gql b/src/graphql/typeDefs/actions_wish_list.gql index 2a3bdaeba31f88cc2dfbb499ea681998ae64c0d8..274d2ec49d9df710dee988585a28947c04b1df3f 100644 --- a/src/graphql/typeDefs/actions_wish_list.gql +++ b/src/graphql/typeDefs/actions_wish_list.gql @@ -83,9 +83,9 @@ const RootQuery = ` sport: String, phone: String, mail: String, - adress: String, + address: String, ip: String - ): [String] + ): [User!] } `; diff --git a/src/graphql/typeDefs/objects_wish_list.gql b/src/graphql/typeDefs/objects_wish_list.gql index a77dd242c74d28331ef5ecd6cfaeb3d136f8d482..98656ba764e164236a9bf6595f92b2e998d6c7e6 100644 --- a/src/graphql/typeDefs/objects_wish_list.gql +++ b/src/graphql/typeDefs/objects_wish_list.gql @@ -151,7 +151,7 @@ const Message = ` views: Int # TODO mettre un commentaire pour expliquer # 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. @@ -174,7 +174,7 @@ const Message = ` participatingUsers: [User] # 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 diff --git a/src/server.js b/src/server.js index 7a982b40ccf85d0763b1875e84f267baf2027240..9f4338399c9906694e73d683a3cd8fda1d27c1fc 100644 --- a/src/server.js +++ b/src/server.js @@ -8,7 +8,7 @@ import express from 'express'; import schema from './graphql/schema'; 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 { ensureLoggedIn } from 'connect-ensure-login'; import passport from 'passport'; @@ -22,15 +22,29 @@ import path from 'path'; import cors from 'cors'; const server = express(); -// on sait pas a quoi ca sert mais il parait que c'est utile -server.use(bodyParser.json()); -server.use(bodyParser.urlencoded({ - extended: true + +// Parse incoming HTTP request bodies, available under the req.body property +// cf www.npmjs.com/package/body-parser +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 + * + * 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 config = JSON.parse(fs.readFileSync(configPath, 'utf8')); @@ -38,11 +52,24 @@ let config = JSON.parse(fs.readFileSync(configPath, 'utf8')); passport.use(new LdapStrategy({ server: { url: config.ldap.server, + //bindDn: '.............', + //bindCredentials: '..........', 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. server.use(session({ @@ -53,18 +80,22 @@ server.use(session({ server.use(passport.initialize()); 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) { - done(null, user); + done(null, user.uid); }); -passport.deserializeUser(function (user, done) { - done(null, user); +//The first argument of deserializeUser corresponds to the key of the user object that was given to the done function in serializeUser +//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 */ -/** - * @description Cache le fait que l'application tourne sous Express dans le header HTTP. - */ +// cache le fait que l'application tourne sous Express dans le header HTTP. server.disable('x-powered-by'); + // setting up view engine for pug console.log("Running at",__dirname); let viewpath = path.resolve(__dirname,'views'); @@ -74,6 +105,7 @@ server.set('view engine', 'pug'); // favicon: capital sigma symbol server.use(favicon(path.resolve('./','assets','favicon.ico'))); +// specifies path to static assets server.use('/assets',express.static(path.resolve('./','assets'))); // Morgan is middleware for logging requests @@ -81,44 +113,53 @@ server.use(morgan('dev')); const defaultUser = require('./../ldap_connexion_config.json'); -/** - * @desc Options de configuration pour le _middleware_ `cors`. - */ +// Options de configuration pour le _middleware_ `cors`. +// CORS = Cross Origin Resource Sharing const corsOptions = { - origin: 'http://localhost:8888', - credentials: true // <-- REQUIRED backend setting + 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 // Configures the Access-Control-Allow-Credentials CORS header. i.e. allows cookies to be included on cross-origin requests }; server.use(cors(corsOptions)); // Charge le middleware express pour GraphQL server.use('/graphql', bodyParser.json(), graphqlExpress(req => { + // vary the options *on a per-request basis* + // (options are passed by using req object as argument) let uid; let password; try { - uid = req.session.passport.user.uid; + uid = req.user.uid; password = "mythe"; } catch (err) { uid = defaultUser.dn.split("=")[1].split(",")[0]; password = defaultUser.passwd; } - // console.log("Accessing GraphQL as:",uid); + // console.log("Accessing GraphQL as: ",uid); return { 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 -server.use('/graphiql', /*ensureLoggedIn('/login'),*/ graphiqlExpress({endpointURL: '/graphql'})); +// GraphiQL est une console interactive pour faire des requêtes GraphQL à la BDD +server.use('/graphiql', + /*ensureLoggedIn('/login'),*/ + graphiqlExpress({endpointURL: '/graphql'}) +); -// GraphQL voyager -server.use('/voyager', graphqlVoyager({ endpointUrl: '/graphql' })); +// GraphQL voyager affiche une représentation sous forme de graphe du schema GraphQL +server.use('/voyager', + /*ensureLoggedIn('/login'),*/ + graphqlVoyager({ endpointUrl: '/graphql' }) +); // connect-flash is middleware for flashing messages +// used in sigma-back's admin interface (admin_view) server.use(flash()); export default server; diff --git a/src/views/home.pug b/src/views/home.pug index ef24d0ba40f508b385756c411a0cb16427c5e103..6a21179d2c8d7bfe22018627b6e52c5e7f5aeca6 100644 --- a/src/views/home.pug +++ b/src/views/home.pug @@ -15,8 +15,7 @@ block content button.form-control(type="submit",class="button") Recherche/<em>Search</em> | h2 GraphiQL and Voyager - p GraphiQL is an interactive environment to make GraphQL - | requests to the database. + p GraphiQL is an interactive environment to make GraphQL requests to the database. 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="/voyager") Voyager