From f79e1b788dbb6363a98fcf97f85924e0c7c40e42 Mon Sep 17 00:00:00 2001 From: asyncnomi Date: Sun, 11 Dec 2022 15:28:43 +0100 Subject: [PATCH] init --- index.js | 354 +++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 16 +++ 2 files changed, 370 insertions(+) create mode 100644 index.js create mode 100644 package.json diff --git a/index.js b/index.js new file mode 100644 index 0000000..e20f8ff --- /dev/null +++ b/index.js @@ -0,0 +1,354 @@ +const fastify = require('fastify')({ logger: true }) +const fs = require('fs'); +const path = require('path') +var LdapAuth = require('ldapauth-fork'); + +let PrankData = JSON.parse(fs.readFileSync("prankdata.txt")); +let AdminUsersUid = ["asyncnomi", "johan", "enthalpine", "fas", "arina", "billy", "remi", "pierre", "", "", "", ""]; +let UsersToken = {}; +let TokenDurationSecond = 3600; + +var LDAP = new LdapAuth({ + url: 'ldap://10.5.0.44', + bindDN: 'cn=zammad,ou=service-users,dc=ldap,dc=rezo-rm,dc=fr', + bindCredentials: 'fenfkjnelnfcsqzjkBZKBDZKclZJdzm', + searchBase: 'dc=ldap,dc=rezo-rm,dc=fr', + searchFilter: '(uid={{username}})', + reconnect: true, +}); +LDAP.on('error', function (err) { + console.error('LdapAuth: ', err); +}); + +fastify.addContentTypeParser('application/json', { + parseAs: 'string' +}, function(req, body, done) { + try { + var json = JSON.parse(body) + done(null, json) + } catch (err) { + err.statusCode = 400 + done(err, undefined) + } +}) + +fastify.register(require('@fastify/static'), { + root: path.join(__dirname, 'static'), + decorateReply: false +}) + +fastify.post('/login', async (request, reply) => { + let content = request.body; + if (content.hasOwnProperty("user") + && content.hasOwnProperty("password")) { + let res = await authenticate(content.user, content.password); + if (res.authState) { + let now = new Date(); + UsersToken[res.authUser.uid] = { + token: makeid(64), + expire: now.setSeconds(now.getSeconds() + TokenDurationSecond) + } + return { + success: true, + user: { + uid: res.authUser.uid, + givenName: res.authUser.givenName + }, + token: UsersToken[res.authUser.uid].token + } + } else { + return { + success: false, + why: "Wrong username or password" + } + } + } else { + return { + success: false, + why: "The username or password is missing" + } + } +}) + +fastify.post('/addPrank', async (request, reply) => { + let content = request.body; + let auth = checkAuthetification(content); + if (auth.success) { + if ("type" in content) { + let note = ("note" in content) ? content.note : "N/A"; + switch (content.type) { + case "crêpe": + if ("where" in content + && "amount" in content) { + let prankUid = makeid(16); + PrankData[prankUid] = { + creator: content.uid, + type: content.type, + where: content.where, + amount: content.amount, + note: content.note, + state: "Pending", + manageBy: null + } + saveData(); + return { + sucess: true, + uid: prankUid, + newPrank: PrankData[prankUid] + } + } else { + return { + success: false, + why: "Missing amount or where" + } + } + break; + case "kidnap": + if ("targetUid" in content + && "when" in content) { + let prankUid = makeid(16); + PrankData[prankUid] = { + creator: content.uid, + type: content.type, + targetUid: content.targetUid, + when: content.when, + note: content.note, + state: "Pending", + manageBy: null + } + saveData(); + return { + sucess: true, + uid: prankUid, + newPrank: PrankData[prankUid] + } + } else { + return { + success: false, + why: "Missing amount or where" + } + } + break; + default: + return { + success: false, + why: "Unknow type" + } + } + } else { + return { + success: false, + why: "Missing type" + } + } + } else { + return auth + } +}) + +fastify.post('/delPrank', async (request, reply) => { + let content = request.body; + let auth = checkAuthetification(content); + if (auth.success) { + let prankExists = checkPrank(content) + if (prankExists.success) { + if (PrankData[content.prankUid].creator === content.uid) { + delete PrankData[content.prankUid]; + return { + success: true, + } + } else { + return { + success: false, + why: "Not allowed" + } + } + } else { + return prankExists + } + } else { + return auth + } +}) + +fastify.post('/acceptPrank', async (request, reply) => { + let content = request.body; + let prankExists = checkManagePrank(content) + if (prankExists.success) { + PrankData[content.prankUid].state = "Accepted"; + PrankData[content.prankUid].manageBy = content.uid; + return { + success: true, + } + } else { + return prankExists + } +}) + +fastify.post('/donePrank', async (request, reply) => { + let content = request.body; + let prankExists = checkManagePrank(content) + if (prankExists.success) { + if (PrankData[content.prankUid].manageBy == content.uid) { + PrankData[content.prankUid].state = "Done"; + return { + success: true, + } + } else { + return { + success: false, + why: "Not allowed" + } + } + } else { + return prankExists + } +}) + +fastify.post('/refusePrank', async (request, reply) => { + let content = request.body; + let prankExists = checkManagePrank(content) + if (prankExists.success) { + PrankData[content.prankUid].state = "Refused"; + PrankData[content.prankUid].manageBy = content.uid; + return { + success: true, + } + } else { + return prankExists + } +}) + +fastify.post('/getPrank', async (request, reply) => { + let content = request.body; + let auth = checkAuthetification(content); + if (auth.success) { + if (AdminUsersUid.includes(content.uid)) { + return { + sucess: true, + prankData: PrankData + } + } else { + return { + success: false, + why: "Not Allowed" + } + } + } else { + return auth + } +}) + + +function saveData() { + fs.writeFileSync('prankdata.txt', JSON.stringify(PrankData)); +} + +function authenticate(user, pwd) { + return new Promise((resolve, reject) => { + LDAP.authenticate(user, pwd, function(err, user) { + if (user && err == null) { + resolve({ + authState: true, + authUser: user + }); + } else { + resolve({ + authState: false, + authUser: null + }); + } + }); + }) +} + +function checkAuthetification(content) { + if (content.hasOwnProperty("uid") + && content.hasOwnProperty("token")) { + if (UsersToken.hasOwnProperty(content.uid) + && UsersToken[content.uid].token === content.token) { + if (UsersToken[content.uid].expire > new Date()) { + return { + success: true + } + } else { + delete UsersToken[content.uid]; + return { + success: false, + why: "Token expired" + } + } + } else { + return { + success: false, + why: "Not authenticated" + } + } + } +} + +function checkPrank(content) { + if ("prankUid" in content) { + if (content.prankUid in PrankData) { + return { + success: true, + } + } else { + return { + success: false, + why: "Unknow prankUid" + } + } + } else { + return { + success: false, + why: "Missing prankUid" + } + } +} + +function checkManagePrank(content) { + let auth = checkAuthetification(content); + if (auth.success) { + if (AdminUsersUid.includes(content.uid)) { + let prankExists = checkPrank(content) + if (prankExists.success) { + return { + success: true + } + } else { + return prankExists + } + } else { + return { + success: false, + why: "Not Allowed" + } + } + } else { + return auth + } +} + +function makeid(length) { + var result = ''; + var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + var charactersLength = characters.length; + for ( var i = 0; i < length; i++ ) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; +} + +const start = async () => { + try { + await fastify.listen({ port: 3000 }) + } catch (err) { + fastify.log.error(err) + LDAP.close(function(err) { + console.log(err); + }) + process.exit(1) + } +} +start() diff --git a/package.json b/package.json new file mode 100644 index 0000000..7edcd5b --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "bde_liste", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "asyncnomi", + "license": "ISC", + "dependencies": { + "@fastify/static": "^6.6.0", + "fastify": "^4.10.2", + "ldapauth-fork": "^5.0.5" + } +}