{_} = require 'underscore' crypto = require('crypto') querystring = require('querystring'); Cookies = require( "cookies" ) request = require 'request' authHeaders = {AUTHUSER: process.env.AUTHUSER, AUTHTOKEN: process.env.AUTHTOKEN} request = request.defaults(json: true, headers: authHeaders, timeout: 30 * 1000) config = require './config' redis = require './redis' USER_KEY = "users" AUTH_KEY = "auth" BANS_KEY = "bans" MUTE_KEY = "mute" return_sso_url="./" secretstring = config.SECRET_KEY loggedin = false # This middleware checks if a user is authenticated through the site. If yes, # then information about the user is stored in req.user. In addition, we store # a token associated with that user into req.user.token. # # User information is also stored in redis. exports.middleware = -> (req, res, next) -> cookies = new Cookies( req, res ) return next() if req.path.match(/^\/css|^\/js|^\/fonts|^\/Sprites|^\/replays\/\b/) return next() if req.path.match(/^\/leaderboard/) # add some proper site authentication later instead authenticate req, (body) -> if !loggedin if req.query.sso sso = req.query.sso sig = req.query.sig cryptedret = crypto.createHmac('SHA256', secretstring).update(sso).digest('hex') if cryptedret != sig return else base64decode = new Buffer(sso, 'base64').toString('ascii') userobject = querystring.parse(base64decode) nonce = cookies.get("nonce") noncereturn = userobject.nonce if noncereturn != nonce return else setdatabasedata(req, cookies, userobject, next) else parameters = getparameters(req) nonce = new Date().getTime() + '' + new Date().getMilliseconds(); cookies.set("nonce", nonce) console.log(req.headers.host) return_sso_url="http://" + req.headers.host + req.url payload = "nonce=" + nonce + "&return_sso_url=" + return_sso_url base64payload = new Buffer(payload).toString('base64') urlencoded = encodeURIComponent(base64payload) crypted = crypto.createHmac('SHA256', secretstring).update(base64payload).digest('hex') return res.redirect("http://forums.p-insurgence.com/session/sso_provider?sso=" + urlencoded + "&sig=" + crypted) exports.matchToken = (req, id, token, next) -> hmac = crypto.createHmac('sha256', config.SECRET_KEY) rawcookies = req.headers.cookie rawcookiesarr = rawcookies.split('; ') noncearr = rawcookiesarr.filter (x) -> x.substring(0, 6) == "nonce=" if (noncearr[0]) noncecookie = noncearr[0].replace("nonce=", "") if token != noncecookie return next(new Error("Invalid session!")) redis.shard 'hget', USER_KEY, id, (err, jsonString) -> if err then return next(err) json = JSON.parse(jsonString) return next(new Error("Invalid session!")) if !json exports.getAuth json.name, (err, authLevel) -> if err then return next(err) json.authority = authLevel return next(null, json) setdatabasedata = (req, cookies, object, next) -> username = object.username id = object.external_id admin = object.admin mod = object.moderator req.user = {} req.user.token = cookies.get("nonce") req.user.id = id req.user.name = username OWNERUSERNAMES = ["Deukhoofd", "thesuzerain"] if username in OWNERUSERNAMES && admin == "true" exports.setAuth username, exports.levels.OWNER else if admin == "true" exports.setAuth username, exports.levels.ADMIN else if mod == "true" exports.setAuth username, exports.levels.MOD else exports.setAuth username, exports.levels.USER toJSON = { name : username, token : cookies.get("nonce") id : id } redis.shard('hset', USER_KEY, id, JSON.stringify(toJSON), next) authenticate = (req, next) -> return next() getparameters = (req) -> return("1") generateUsername = (req) -> name = req.param('user') return name if name {SpeciesData} = require './xy/data' randomName = (name for name of SpeciesData) randomName = randomName[Math.floor(Math.random() * randomName.length)] randomName = randomName.split(/\s+/)[0] randomName += "Fan" + Math.floor(Math.random() * 10000) randomName generateId = (req) -> req.param('id') || Math.floor(1000000 * Math.random()) generateUser = (req) -> {id: generateId(req), username: generateUsername(req)} # Authorization exports.levels = USER : 1 DRIVER : 2 MOD : 3 MODERATOR : 3 ADMIN : 4 ADMINISTRATOR : 4 OWNER : 5 LEVEL_VALUES = (value for key, value of exports.levels) exports.getAuth = (id, next) -> id = String(id).toLowerCase() redis.hget AUTH_KEY, id, (err, auth) -> if err then return next(err) auth = parseInt(auth, 10) || exports.levels.USER next(null, auth) exports.setAuth = (id, newAuthLevel, next) -> id = String(id).toLowerCase() if newAuthLevel not in LEVEL_VALUES next(new Error("Incorrect auth level: #{newAuthLevel}")) redis.hset(AUTH_KEY, id, newAuthLevel, next) # Ban # Length is in seconds. exports.ban = (id, reason, length, next) -> id = id.toLowerCase() key = "#{BANS_KEY}:#{id}" if length > 0 redis.setex(key, length, reason, next) else redis.set(key, reason, next) exports.unban = (id, next) -> id = String(id).toLowerCase() redis.del("#{BANS_KEY}:#{id}", next) exports.getBanReason = (id, next) -> id = String(id).toLowerCase() redis.get("#{BANS_KEY}:#{id}", next) exports.getBanTTL = (id, next) -> id = String(id).toLowerCase() key = "#{BANS_KEY}:#{id}" redis.exists key, (err, result) -> if !result # In older versions of Redis, TTL returns -1 if key doesn't exist. return next(null, -2) else redis.ttl(key, next) # Mute # Length is in seconds. exports.mute = (id, reason, length, next) -> id = String(id).toLowerCase() key = "#{MUTE_KEY}:#{id}" if length > 0 redis.setex(key, length, reason, next) else redis.set(key, reason, next) exports.unmute = (id, next) -> id = String(id).toLowerCase() key = "#{MUTE_KEY}:#{id}" redis.del(key, next) exports.getMuteTTL = (id, next) -> id = String(id).toLowerCase() key = "#{MUTE_KEY}:#{id}" redis.exists key, (err, result) -> if !result # In older versions of Redis, TTL returns -1 if key doesn't exist. return next(null, -2) else redis.ttl(key, next)