Revert "Revert "add oauth2-server""

This reverts commit 946a7c2494d39fd7581cb8a068af7df647fb3bda.

GitOrigin-RevId: 2f02e9d9e2d0348e4ea1d447e0291fae72c0008a
This commit is contained in:
Ersun Warncke 2019-05-14 05:27:21 -04:00 committed by sharelatex
parent 9b24ed6daa
commit 7883554d73
7 changed files with 280 additions and 74 deletions

View file

@ -187,8 +187,25 @@ module.exports = AuthenticationController =
return doRequest return doRequest
requireOauth: () -> requireOauth: () ->
# require this here because module may not be included in some versions
Oauth2Server = require "../../../../modules/oauth2-server/app/js/Oauth2Server"
return (req, res, next = (error) ->) -> return (req, res, next = (error) ->) ->
return res.status(401).send() unless req.token? request = new Oauth2Server.Request(req)
response = new Oauth2Server.Response(res)
Oauth2Server.server.authenticate request, response, {}, (err, token) ->
if err?
# fall back to v1 on invalid token
return AuthenticationController._requireOauthV1Fallback req, res, next if err.code == 401
# bubble up all other errors
return next(err)
req.oauth =
access_token: token.accessToken
req.oauth_token = token
req.oauth_user = token.user
return next()
_requireOauthV1Fallback: (req, res, next) ->
return res.sendStatus 401 unless req.token?
options = options =
expectedStatusCodes: [401] expectedStatusCodes: [401]
json: token: req.token json: token: req.token
@ -199,11 +216,10 @@ module.exports = AuthenticationController =
return res.status(401).json({error: "invalid_token"}) unless body?.user_profile?.id return res.status(401).json({error: "invalid_token"}) unless body?.user_profile?.id
User.findOne { "overleaf.id": body.user_profile.id }, (error, user) -> User.findOne { "overleaf.id": body.user_profile.id }, (error, user) ->
return next(error) if error? return next(error) if error?
return res.status(401).send({error: "invalid_token"}) unless user? return res.status(401).json({error: "invalid_token"}) unless user?
req.oauth = req.oauth =
access_token: body.access_token access_token: body.access_token
collabratec_customer_id: body.collabratec_customer_id user.collabratec_id = body.collabratec_customer_id unless user.collabratec_id?
user_profile: body.user_profile
req.oauth_user = user req.oauth_user = user
next() next()

View file

@ -0,0 +1,31 @@
mongoose = require 'mongoose'
Settings = require 'settings-sharelatex'
Schema = mongoose.Schema
ObjectId = Schema.ObjectId
OauthAccessTokenSchema = new Schema(
{
accessToken: String
accessTokenExpiresAt: Date
oauthApplication_id: { type: ObjectId, ref: 'OauthApplication' }
refreshToken: String
refreshTokenExpiresAt: Date
scope: String
user_id: { type: ObjectId, ref: 'User' }
},
{
collection: 'oauthAccessTokens'
}
)
conn = mongoose.createConnection(Settings.mongo.url, {
server: {poolSize: Settings.mongo.poolSize || 10},
config: {autoIndex: false}
})
OauthAccessToken = conn.model('OauthAccessToken', OauthAccessTokenSchema)
mongoose.model 'OauthAccessToken', OauthAccessTokenSchema
exports.OauthAccessToken = OauthAccessToken
exports.OauthAccessTokenSchema = OauthAccessTokenSchema

View file

@ -0,0 +1,30 @@
mongoose = require 'mongoose'
Settings = require 'settings-sharelatex'
Schema = mongoose.Schema
ObjectId = Schema.ObjectId
OauthApplicationSchema = new Schema(
{
id: String
clientSecret: String
grants: [ String ]
name: String
redirectUris: [ String ]
scopes: [ String ]
},
{
collection: 'oauthApplications'
}
)
conn = mongoose.createConnection(Settings.mongo.url, {
server: {poolSize: Settings.mongo.poolSize || 10},
config: {autoIndex: false}
})
OauthApplication = conn.model('OauthApplication', OauthApplicationSchema)
mongoose.model 'OauthApplication', OauthApplicationSchema
exports.OauthApplication = OauthApplication
exports.OauthApplicationSchema = OauthApplicationSchema

View file

@ -0,0 +1,30 @@
mongoose = require 'mongoose'
Settings = require 'settings-sharelatex'
Schema = mongoose.Schema
ObjectId = Schema.ObjectId
OauthAuthorizationCodeSchema = new Schema(
{
authorizationCode: String
expiresAt: Date
oauthApplication_id: { type: ObjectId, ref: 'OauthApplication' }
redirectUri: String
scope: String
user_id: { type: ObjectId, ref: 'User' }
},
{
collection: 'oauthAuthorizationCodes'
}
)
conn = mongoose.createConnection(Settings.mongo.url, {
server: {poolSize: Settings.mongo.poolSize || 10},
config: {autoIndex: false}
})
OauthAuthorizationCode = conn.model('OauthAuthorizationCode', OauthAuthorizationCodeSchema)
mongoose.model 'OauthAuthorizationCode', OauthAuthorizationCodeSchema
exports.OauthAuthorizationCode = OauthAuthorizationCode
exports.OauthAuthorizationCodeSchema = OauthAuthorizationCodeSchema

View file

@ -2139,6 +2139,18 @@
"resolved": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz", "resolved": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz",
"integrity": "sha1-6sFuA+oUOO/5Qj1puqNiYu0fcLs=" "integrity": "sha1-6sFuA+oUOO/5Qj1puqNiYu0fcLs="
}, },
"basic-auth": {
"version": "2.0.1",
"from": "basic-auth@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
"from": "safe-buffer@5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
}
}
},
"basic-auth-connect": { "basic-auth-connect": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/basic-auth-connect/-/basic-auth-connect-1.0.0.tgz", "resolved": "https://registry.npmjs.org/basic-auth-connect/-/basic-auth-connect-1.0.0.tgz",
@ -3550,6 +3562,16 @@
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
}, },
"co-bluebird": {
"version": "1.1.0",
"from": "co-bluebird@>=1.1.0 <2.0.0",
"resolved": "https://registry.npmjs.org/co-bluebird/-/co-bluebird-1.1.0.tgz"
},
"co-use": {
"version": "1.1.0",
"from": "co-use@>=1.1.0 <2.0.0",
"resolved": "https://registry.npmjs.org/co-use/-/co-use-1.1.0.tgz"
},
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
@ -8431,6 +8453,11 @@
"number-is-nan": "^1.0.0" "number-is-nan": "^1.0.0"
} }
}, },
"is-generator": {
"version": "1.0.3",
"from": "is-generator@>=1.0.2 <2.0.0",
"resolved": "https://registry.npmjs.org/is-generator/-/is-generator-1.0.3.tgz"
},
"is-glob": { "is-glob": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
@ -12576,6 +12603,43 @@
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
"integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
}, },
"oauth2-server": {
"version": "3.0.1",
"from": "oauth2-server@latest",
"resolved": "https://registry.npmjs.org/oauth2-server/-/oauth2-server-3.0.1.tgz",
"dependencies": {
"bluebird": {
"version": "3.5.3",
"from": "bluebird@>=3.5.1 <4.0.0",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz"
},
"lodash": {
"version": "4.17.11",
"from": "lodash@>=4.17.10 <5.0.0",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz"
},
"mime-db": {
"version": "1.38.0",
"from": "mime-db@>=1.38.0 <1.39.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz"
},
"mime-types": {
"version": "2.1.22",
"from": "mime-types@>=2.1.18 <2.2.0",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz"
},
"statuses": {
"version": "1.5.0",
"from": "statuses@>=1.5.0 <2.0.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz"
},
"type-is": {
"version": "1.6.16",
"from": "type-is@>=1.6.16 <2.0.0",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz"
}
}
},
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@ -14074,6 +14138,11 @@
"is-promise": "~1" "is-promise": "~1"
} }
}, },
"promisify-any": {
"version": "2.0.1",
"from": "promisify-any@>=2.0.1 <3.0.0",
"resolved": "https://registry.npmjs.org/promisify-any/-/promisify-any-2.0.1.tgz"
},
"promisify-call": { "promisify-call": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/promisify-call/-/promisify-call-2.0.4.tgz", "resolved": "https://registry.npmjs.org/promisify-call/-/promisify-call-2.0.4.tgz",

View file

@ -79,6 +79,7 @@
"nodemailer-sendgrid-transport": "^0.2.0", "nodemailer-sendgrid-transport": "^0.2.0",
"nodemailer-ses-transport": "^1.3.0", "nodemailer-ses-transport": "^1.3.0",
"nvd3": "^1.8.6", "nvd3": "^1.8.6",
"oauth2-server": "^3.0.1",
"optimist": "0.6.1", "optimist": "0.6.1",
"overleaf-error-type": "git+https://github.com/overleaf/overleaf-error-type.git", "overleaf-error-type": "git+https://github.com/overleaf/overleaf-error-type.git",
"passport": "^0.3.2", "passport": "^0.3.2",

View file

@ -37,6 +37,10 @@ describe "AuthenticationController", ->
ipMatcherAffiliation: sinon.stub() ipMatcherAffiliation: sinon.stub()
"../V1/V1Api": @V1Api = request: sinon.stub() "../V1/V1Api": @V1Api = request: sinon.stub()
"../../models/User": { User: @UserModel } "../../models/User": { User: @UserModel }
"../../../../modules/oauth2-server/app/js/Oauth2Server": @Oauth2Server =
Request: sinon.stub()
Response: sinon.stub()
server: authenticate: sinon.stub()
@user = @user =
_id: ObjectId() _id: ObjectId()
email: @email = "USER@example.com" email: @email = "USER@example.com"
@ -402,16 +406,41 @@ describe "AuthenticationController", ->
describe "requireOauth", -> describe "requireOauth", ->
beforeEach -> beforeEach ->
@res.sendStatus = sinon.stub()
@res.send = sinon.stub() @res.send = sinon.stub()
@res.status = sinon.stub().returns(@res) @res.status = sinon.stub().returns(@res)
@middleware = @AuthenticationController.requireOauth() @middleware = @AuthenticationController.requireOauth()
describe "when Oauth2Server authenticates", ->
beforeEach ->
@token =
accessToken: "token"
user: "user"
@Oauth2Server.server.authenticate.yields null, @token
@middleware(@req, @res, @next)
it "should set oauth_token on request", ->
@req.oauth_token.should.equal @token
it "should set oauth on request", ->
@req.oauth.access_token.should.equal @token.accessToken
it "should set oauth_user on request", ->
@req.oauth_user.should.equal "user"
it "should call next", ->
@next.should.have.been.calledOnce
describe "when Oauth2Server does not authenticate", ->
beforeEach ->
@Oauth2Server.server.authenticate.yields code: 401
describe "when token not provided", -> describe "when token not provided", ->
beforeEach -> beforeEach ->
@middleware(@req, @res, @next) @middleware(@req, @res, @next)
it "should return 401 error", -> it "should return 401 error", ->
@res.status.should.have.been.calledWith 401 @res.sendStatus.should.have.been.calledWith 401
describe "when token provided", -> describe "when token provided", ->
beforeEach -> beforeEach ->