Browse Source

slack login

B Thibault 8 years ago
parent
commit
dbd4a2d926
10 changed files with 235 additions and 1 deletions
  1. 0 0
      index.html
  2. 13 0
      package.json
  3. 0 1
      src/.htaccess
  4. 5 0
      src/config.js
  5. 4 0
      src/main.js
  6. 5 0
      src/public/index.html
  7. 98 0
      src/src/httpServ.js
  8. 50 0
      src/src/session.js
  9. 10 0
      src/src/slack.js
  10. 50 0
      src/src/url.js

+ 0 - 0
index.html


+ 13 - 0
package.json

@@ -0,0 +1,13 @@
+{
+	"name": "knackigate-slack"
+	,"dependencies": [
+		"http"
+		,"client-sessions"
+		,"crypto"
+		,"sleep"
+	]
+	,"repository": {
+		"type": "git"
+		,"url": "git@git.knacki.info:isundil/knackigate-slack"
+	}
+}

+ 0 - 1
src/.htaccess

@@ -1 +0,0 @@
-DENY FROM all

+ 5 - 0
src/config.js

@@ -0,0 +1,5 @@
+
+module.exports = {
+    clientId: "secret client id"
+    ,rootUrl: "local url"
+};

+ 4 - 0
src/main.js

@@ -0,0 +1,4 @@
+var Server = require("./src/httpServ.js").HttpServ;
+
+var server = new Server(3002);
+

+ 5 - 0
src/public/index.html

@@ -0,0 +1,5 @@
+<html>
+	<body>
+		<script src="cli.js"></script>
+	</body>
+</html>

+ 98 - 0
src/src/httpServ.js

@@ -0,0 +1,98 @@
+var http = require("http")
+    ,clientSession = require("client-sessions")
+    ,sleep = require("sleep").sleep
+
+    ,Url = require("./url.js").Url
+    ,Slack = require("./slack.js").Slack
+    ,config = require("../config.js")
+    ,sessionManager = require("./session.js").SessionManager;
+
+function Server(port) {
+    var ctx = this;
+
+    this.httpServ = http.createServer(function(req, res) {
+        ctx.onRequest(req, res);
+    });
+    this.httpServ.listen(port, ctx.onListen);
+}
+
+Server.parseCookies = function(req) {
+    var cookies = req.headers.cookie
+    ,cookieObj = null;
+
+    if (cookies) {
+    cookieObj = {};
+        cookies = cookies.split(";");
+    for (var cookieIndex =0, nbCookies =cookies.length; cookieIndex < nbCookies; cookieIndex++) {
+        var cookieParts = cookies[cookieIndex].indexOf("=")
+        ,cookieKey = null
+        ,cookieValue = null;
+
+            if (cookieParts === -1) {
+        cookieKey = cookies[cookieIndex].trim();
+        } else {
+        cookieKey = cookies[cookieIndex].substr(0, cookieParts).trim();
+        cookieValue = cookies[cookieIndex].substr(cookieParts +1).trim();
+        }
+        cookieObj[cookieKey] = cookieValue;
+    }
+    }
+    return cookieObj;
+}
+
+Server.stringifyCookies = function(cookies) {
+    var cookieString = "";
+    for (var cookieKey in cookies) {
+    cookieString += cookieString;
+    if (cookies[cookieString] !== null) {
+        cookieString += "=";
+    }
+    cookieString += "; ";
+    }
+    return cookieString;
+}
+
+Server.prototype.onListen = function() {
+    console.log("onListen");
+}
+
+Server.prototype.onRequest = function(req, res) {
+    req.reqT = Date.now();
+    req.cookies = Server.parseCookies(req);
+    req.session = sessionManager.forRequest(req);
+    req.urlObj = new Url(req.url);
+
+    if ((!req.session || !req.session.slackToken) && false) {
+        if (req.urlObj.queryTokens.code) {
+        req.session = sessionManager.lazyForRequest(req);
+        req.session.setSlackToken(req.reqT, req.urlObj.queryTokens.code[0]);
+            res.writeHeader("302", {
+                Location: config.rootUrl
+            ,"Set-Cookie": "sessID="+req.session.sessId
+            });
+        } else {
+            res.writeHeader("302", {
+                Location: "https://slack.com/oauth/authorize"
+                +"?client_id=" +config.clientId
+                +"&scope=" +Slack.getScope().join(" ")
+                +"&redirect=" +config.rootUrl
+            });
+        }
+    } else if (req.urlObj.isPublic()) {
+        res.setHeader('Cache-Control', 'public, max-age=' +15 * 60);
+        res.setHeader('Content-Length', req.urlObj.serve.stat.size);
+        res.writeHeader("200");
+        req.urlObj.getReadStream().pipe(res, { end: true });
+        return; // async pipe will close when finished
+    } else {
+        res.writeHeader("200");
+        res.write('"' +Math.floor(Date.now() /1000) +'"');
+    }
+    if (req.session && req.session.modifiedAt === req.reqT) {
+        sessionManager.saveSession(req.session);
+    }
+    res.end();
+}
+
+module.exports.HttpServ = Server;
+

+ 50 - 0
src/src/session.js

@@ -0,0 +1,50 @@
+var crypto = require('crypto');
+
+function SessionManager() {
+//  TODO cache-able
+    this.sessions = {};
+}
+
+function Session(reqT, sessId) {
+    this.sessId = sessId;
+    this.slackToken = null;
+    this.modifiedAt = reqT;
+}
+
+SessionManager.createSessionId = function(req) {
+    var token = Date.now() + "" +Math.random();
+    return crypto.createHash('md5').update(token).digest('hex');
+}
+
+SessionManager.prototype.forRequest = function(request) {
+    if (request.cookies && request.cookies.sessID && this.sessions[request.cookies.sessID]) {
+        return this.sessions[request.cookies.sessID];
+    }
+    return null;
+}
+
+SessionManager.prototype.lazyForRequest = function(request) {
+    var session = this.forRequest(request);
+    if (session) {
+        return session;
+    }
+    var sessionId = SessionManager.createSessionId(request);
+    session = new Session(request.reqT, sessionId);
+    this.sessions[sessionId] = session;
+    return session;
+}
+
+SessionManager.prototype.saveSession = function(session) {
+    console.log("saving " +session.sessId);
+}
+
+Session.prototype.setSlackToken = function(reqT, slackToken) {
+    console.log(slackToken);
+    this.slackToken = slackToken;
+    this.modifiedAt = reqT;
+}
+
+var sessMan = new SessionManager();
+
+module.exports.SessionManager = sessMan;
+

+ 10 - 0
src/src/slack.js

@@ -0,0 +1,10 @@
+
+function Slack() {
+}
+
+Slack.getScope = function() {
+    return [ "channels:read", "chat:write:user" ];
+}
+
+module.exports.Slack = Slack;
+

+ 50 - 0
src/src/url.js

@@ -0,0 +1,50 @@
+var fs = require('fs');
+
+function Url(url) {
+    this.url = url;
+    while (this.url.length && this.url[0] === '/') {
+        this.url = this.url.substr(1);
+    }
+    this.urlParts = this.url.split("/");
+    var stop = url.indexOf("?");
+    if (stop === -1) {
+        stop = url.length;
+    }
+    this.path = url.substr(0, stop);
+    var queryTokens = url.substr(stop +1).split("&");
+    this.queryTokens = {};
+    for (var i =0, nbTokens = queryTokens.length; i < nbTokens; i++) {
+        var token = queryTokens[i].split("=");
+        if (token[0] !== "") {
+            if (!this.queryTokens[token[0]]) {
+                this.queryTokens[token[0]] = [];
+            }
+            this.queryTokens[token[0]].push(token[1] || true);
+        }
+    }
+    this.serve = null;
+    try{
+        if (this.urlParts.length == 1 && this.urlParts[0] == '') {
+            this.serve = {
+                filename: "public/index.html"
+                ,stat: fs.statSync("public/index.html")
+            };
+        } else if (this.urlParts.length == 1) {
+            this.serve = {
+                filename: "public/" +this.urlParts[0]
+                ,stat: fs.statSync("public/" +this.urlParts[0])
+            };
+        }
+    } catch (e) {
+    }
+}
+
+Url.prototype.isPublic = function() {
+    return this.serve !== null;
+}
+
+Url.prototype.getReadStream = function() {
+    return fs.createReadStream(this.serve.filename);
+}
+
+module.exports = { Url: Url };