Initial draft of clever integration.

This commit is contained in:
Rob 2016-09-13 15:18:19 -07:00
parent 6e2e3d5cb7
commit 8359c95489
5 changed files with 80 additions and 0 deletions

View file

@ -64,6 +64,7 @@ _.extend UserSchema.properties,
facebookID: c.shortString({title: 'Facebook ID'}) facebookID: c.shortString({title: 'Facebook ID'})
githubID: {type: 'integer', title: 'GitHub ID'} githubID: {type: 'integer', title: 'GitHub ID'}
gplusID: c.shortString({title: 'G+ ID'}) gplusID: c.shortString({title: 'G+ ID'})
cleverID: c.shortString({title: 'Clever ID'})
wizardColor1: c.pct({title: 'Wizard Clothes Color'}) # No longer used wizardColor1: c.pct({title: 'Wizard Clothes Color'}) # No longer used
volume: c.pct({title: 'Volume'}) volume: c.pct({title: 'Volume'})

View file

@ -11,6 +11,7 @@ mongoose = require 'mongoose'
authentication = require 'passport' authentication = require 'passport'
sendwithus = require '../sendwithus' sendwithus = require '../sendwithus'
LevelSession = require '../models/LevelSession' LevelSession = require '../models/LevelSession'
config = require '../../server_config'
module.exports = module.exports =
checkDocumentPermissions: (req, res, next) -> checkDocumentPermissions: (req, res, next) ->
@ -62,6 +63,11 @@ module.exports =
yield req.user.update {activity: activity} yield req.user.update {activity: activity}
res.status(200).send(req.user.toObject({req: req})) res.status(200).send(req.user.toObject({req: req}))
redirectHome: wrap (req, res, next) ->
activity = req.user.trackActivity 'login', 1
yield req.user.update {activity: activity}
res.redirect '/'
loginByGPlus: wrap (req, res, next) -> loginByGPlus: wrap (req, res, next) ->
gpID = req.body.gplusID gpID = req.body.gplusID
gpAT = req.body.gplusAccessToken gpAT = req.body.gplusAccessToken
@ -77,6 +83,73 @@ module.exports =
yield req.logInAsync(user) yield req.logInAsync(user)
next() next()
loginByClever: wrap (req, res, next) ->
throw new errors.UnprocessableEntity('Clever integration not configured.') unless config.clever.client_id and config.clever.client_secret
code = req.query.code
scope = req.query.scope
throw new errors.UnprocessableEntity('code and scope required.') unless code and scope
[cleverRes, auth] = yield request.postAsync
json: true
url: "https://clever.com/oauth/tokens"
form:
code: code
grant_type: 'authorization_code'
redirect_uri: 'http://localhost:3000/auth/login-clever'
auth:
user: config.clever.client_id
password: config.clever.client_secret
sendImmediately: true
throw new errors.UnprocessableEntity('Invalid Clever OAuth Code.') unless auth.access_token
[re2, userInfo] = yield request.getAsync
json : true
url: 'https://api.clever.com/me'
auth:
bearer: auth.access_token
[lookupRes, lookup] = yield request.getAsync
url: "https://api.clever.com/v1.1/#{userInfo.data.type}s/#{userInfo.data.id}"
json: true
auth:
bearer: auth.access_token
unless lookupRes.statusCode is 200
throw new errors.Forbidden("Couldn't look up user. Is data sharing enabled in clever?")
user = yield User.findOne({cleverID: userInfo.data.id})
unless user
user = new User
anonymous: false
role: if userInfo.data.type is 'student' then 'student' else 'teacher'
cleverID: userInfo.data.id
emailVerified: true
email: lookup.data.email
user.set 'testGroupNumber', Math.floor(Math.random() * 256) # also in app/core/auth
if lookup.data.name
user.set 'firstName', lookup.data.name.first
user.set 'lastName', lookup.data.name.last
yield user.save()
#console.log JSON.stringify
# userInfo: userInfo
# lookup: lookup
#,null,' '
req.logInAsync = Promise.promisify(req.logIn)
yield req.logInAsync(user)
next()
loginByFacebook: wrap (req, res, next) -> loginByFacebook: wrap (req, res, next) ->
fbID = req.body.facebookID fbID = req.body.facebookID
fbAT = req.body.facebookAccessToken fbAT = req.body.facebookAccessToken

View file

@ -27,6 +27,7 @@ UserSchema.index({'dateCreated': 1})
UserSchema.index({'emailLower': 1}, {unique: true, sparse: true, name: 'emailLower_1'}) UserSchema.index({'emailLower': 1}, {unique: true, sparse: true, name: 'emailLower_1'})
UserSchema.index({'facebookID': 1}, {sparse: true}) UserSchema.index({'facebookID': 1}, {sparse: true})
UserSchema.index({'gplusID': 1}, {sparse: true}) UserSchema.index({'gplusID': 1}, {sparse: true})
UserSchema.index({'cleverID': 1}, {sparse: true})
UserSchema.index({'iosIdentifierForVendor': 1}, {name: 'iOS identifier for vendor', sparse: true, unique: true}) UserSchema.index({'iosIdentifierForVendor': 1}, {name: 'iOS identifier for vendor', sparse: true, unique: true})
UserSchema.index({'mailChimp.leid': 1}, {sparse: true}) UserSchema.index({'mailChimp.leid': 1}, {sparse: true})
UserSchema.index({'nameLower': 1}, {sparse: true, name: 'nameLower_1'}) UserSchema.index({'nameLower': 1}, {sparse: true, name: 'nameLower_1'})

View file

@ -6,6 +6,7 @@ module.exports.setup = (app) ->
app.post('/auth/login', passport.authenticate('local'), mw.auth.afterLogin) app.post('/auth/login', passport.authenticate('local'), mw.auth.afterLogin)
app.post('/auth/login-facebook', mw.auth.loginByFacebook, mw.auth.afterLogin) app.post('/auth/login-facebook', mw.auth.loginByFacebook, mw.auth.afterLogin)
app.post('/auth/login-gplus', mw.auth.loginByGPlus, mw.auth.afterLogin) app.post('/auth/login-gplus', mw.auth.loginByGPlus, mw.auth.afterLogin)
app.get('/auth/login-clever', mw.auth.loginByClever, mw.auth.redirectHome)
app.post('/auth/logout', mw.auth.logout) app.post('/auth/logout', mw.auth.logout)
app.get('/auth/name/?(:name)?', mw.auth.name) app.get('/auth/name/?(:name)?', mw.auth.name)
app.get('/auth/email/?(:email)?', mw.auth.email) app.get('/auth/email/?(:email)?', mw.auth.email)

View file

@ -79,6 +79,10 @@ config.hipchat =
config.slackToken = process.env.COCO_SLACK_TOKEN or '' config.slackToken = process.env.COCO_SLACK_TOKEN or ''
config.clever =
client_id: process.env.COCO_CLEVER_CLIENTID
client_secret: process.env.COCO_CLEVER_SECRET
config.queue = config.queue =
accessKeyId: process.env.COCO_AWS_ACCESS_KEY_ID or '' accessKeyId: process.env.COCO_AWS_ACCESS_KEY_ID or ''
secretAccessKey: process.env.COCO_AWS_SECRET_ACCESS_KEY or '' secretAccessKey: process.env.COCO_AWS_SECRET_ACCESS_KEY or ''