Add PicoCTF backend support.

This commit is contained in:
Rob 2016-02-16 15:58:29 -08:00
parent c2f02ebbfb
commit 0aa3418e44
4 changed files with 88 additions and 1 deletions

64
server/lib/picoctf.coffee Normal file
View file

@ -0,0 +1,64 @@
config = require '../../server_config'
request = require 'request'
User = require '../users/User'
http = require 'http'
authstr = new Buffer("#{config.picoCTF_auth.username}:#{config.picoCTF_auth.password}").toString 'base64'
papi = (url, req, cb) ->
request
url: "#{config.picoCTF_api_url}#{url}"
headers:
Cookie: "flask=#{req.cookies.flask}"
Authorization: 'Basic ' + authstr
, cb
class PicoStrategy
constructor: () ->
@name = 'local'
authenticate: (req) ->
papi "/team", req, (err, rr, body) =>
return @fail err if err
response = JSON.parse(body)
return @fail response.message if response.status is 0
data = response.data
tid = data.tid
fakeEmail = "#{tid}@coco.team"
User.findOne(emailLower: fakeEmail).exec (err, user) =>
return @success user if user
user = new User
anonymous: false
name: data.team_name
email: fakeEmail
emailLower: fakeEmail
user.set 'testGroupNumber', Math.floor(Math.random() * 256) # also in app/core/auth
user.save (err) =>
console.log "New user created!", user
@success user
init = (app) ->
app.get '/picoctf/problems', (req, res) ->
papi "/problems/unlocked", req, (err, rr, body) ->
res.json JSON.parse(body).data
app.get '/picoctf/problems/all', (req, res) ->
papi "/problems/all", req, (err, rr, body) ->
res.json JSON.parse(body).data
app.post '/picoctf/submit', (req, res) ->
request
url: "#{config.picoCTF_APIURL}/submit"
headers:
Cookie: "flask=#{req.cookies.flask}"
Authorization: 'Basic ' + authstr
, (err, rr, body) ->
res.json JSON.parse(body)
module.exports =
PicoStrategy: PicoStrategy
init: init

View file

@ -15,6 +15,11 @@ module.exports.setup = (app) ->
authentication.deserializeUser((id, done) ->
User.findById(id, (err, user) -> done(err, user)))
if config.picoCTF
pico = require('../lib/picoctf');
authentication.use new pico.PicoStrategy()
return
authentication.use(new LocalStrategy(
(username, password, done) ->

View file

@ -80,6 +80,15 @@ config.cookie_secret = process.env.COCO_COOKIE_SECRET or 'chips ahoy'
config.isProduction = config.mongo.host isnt 'localhost'
if process.env.COCO_PICOCTF
config.picoCTF = true
config.picoCTF_api_url = 'http://staging.picoctf.com/api'
config.picoCTF_login_URL = 'http://staging.picoctf.com'
config.picoCTF_auth = {username: 'picodev', password: 'pico2016rox!ftw'}
else
config.picoCTF = false
if not config.unittest and not config.isProduction
# change artificially slow down non-static requests for testing
config.slow_down = false

View file

@ -79,7 +79,11 @@ setupExpressMiddleware = (app) ->
setupPassportMiddleware = (app) ->
app.use(authentication.initialize())
app.use(authentication.session())
if config.picoCTF
app.use authentication.authenticate('local', failureRedirect: config.picoCTF_login_URL)
require('./server/lib/picoctf').init app
else
app.use(authentication.session())
setupCountryRedirectMiddleware = (app, country="china", countryCode="CN", languageCode="zh", serverID="tokyo") ->
shouldRedirectToCountryServer = (req) ->
@ -157,6 +161,11 @@ setupFallbackRouteToIndex = (app) ->
log.error "Error modifying main.html: #{err}" if err
# insert the user object directly into the html so the application can have it immediately. Sanitize </script>
user = if req.user then JSON.stringify(UserHandler.formatEntity(req, req.user)).replace(/\//g, '\\/') else '{}'
data = data.replace '"serverConfigTag"', JSON.stringify
picoCTF: config.picoCTF,
production: config.isProduction
data = data.replace('"userObjectTag"', user)
res.header 'Cache-Control', 'no-cache, no-store, must-revalidate'
res.header 'Pragma', 'no-cache'