Fix authentication api changes

Co-authored-by: gizmo1-11 <thom_schu@gmx.de>
This commit is contained in:
yzx9 2023-08-13 23:48:09 +08:00
parent a6448a51e9
commit f645454a74

View File

@ -24,6 +24,7 @@ const DiffHelper = require('../Helpers/DiffHelper')
const Metrics = require('@overleaf/metrics') const Metrics = require('@overleaf/metrics')
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
const fs = require("fs")
const { Client } = require("ldapts") const { Client } = require("ldapts")
const ldapEscape = require("ldap-escape") const ldapEscape = require("ldap-escape")
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
@ -78,19 +79,9 @@ const AuthenticationManager = {
if (error) { if (error) {
return callback(error) return callback(error)
} }
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> if (!user || !user.hashedPassword) {
if (!process.env.ALLOW_EMAIL_LOGIN || !user || !user.hashedPassword) { return callback(null, null, null)
// No local passwd check user has to be in ldap and use ldap credentials
return AuthenticationManager.ldapAuth(
query,
password,
AuthenticationManager.createIfNotExistAndLogin,
callback,
user
)
} }
console.log("email login for existing user " + query.email)
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
bcrypt.compare(password, user.hashedPassword, function (error, match) { bcrypt.compare(password, user.hashedPassword, function (error, match) {
if (error) { if (error) {
return callback(error) return callback(error)
@ -98,30 +89,29 @@ const AuthenticationManager = {
if (match) { if (match) {
_metricsForSuccessfulPasswordMatch(password) _metricsForSuccessfulPasswordMatch(password)
} }
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
else {
console.log("Local user password mismatch, trying LDAP")
// check passwd against ldap
return AuthenticationManager.ldapAuth(
query,
password,
AuthenticationManager.createIfNotExistAndLogin,
callback,
user
)
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
callback(null, user, match) callback(null, user, match)
}) })
}) })
}, },
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_checkUserPassword2(query, password, callback) {
// leave original _checkUserPassword untouched, because it will be called by
// setUserPasswordInV2 (e.g. UserRegistrationHandler.js )
User.findOne(query, (error, user) => {
AuthenticationManager.authUserObj(error, user, query, password, callback)
})
},
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
authenticate(query, password, auditLog, callback) { authenticate(query, password, auditLog, callback) {
if (typeof callback === 'undefined') { if (typeof callback === 'undefined') {
callback = auditLog callback = auditLog
auditLog = null auditLog = null
} }
AuthenticationManager._checkUserPassword( // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
AuthenticationManager._checkUserPassword2(
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
query, query,
password, password,
(error, user, match) => { (error, user, match) => {
@ -191,22 +181,12 @@ const AuthenticationManager = {
* login with any password * login with any password
*/ */
login(user, password, callback) { login(user, password, callback) {
AuthenticationManager.checkRounds( callback(null, user, true)
user,
user.hashedPassword,
password,
function (err) {
if (err) {
return callback(err)
}
callback(null, user)
}
)
}, },
createIfNotExistAndLogin( createIfNotExistAndLogin(
query, query,
user, user1,
callback, callback,
uid, uid,
firstname, firstname,
@ -214,7 +194,7 @@ const AuthenticationManager = {
mail, mail,
isAdmin isAdmin
) { ) {
if (!user) { if (!user1) {
//console.log('Creating User:' + JSON.stringify(query)) //console.log('Creating User:' + JSON.stringify(query))
//create random pass for local userdb, does not get checked for ldap users during login //create random pass for local userdb, does not get checked for ldap users during login
let pass = require("crypto").randomBytes(32).toString("hex") let pass = require("crypto").randomBytes(32).toString("hex")
@ -228,7 +208,7 @@ const AuthenticationManager = {
last_name: lastname, last_name: lastname,
password: pass, password: pass,
}, },
function (error, user) { function (error, user, setNewPasswordUrl) {
if (error) { if (error) {
console.log(error) console.log(error)
} }
@ -248,7 +228,7 @@ const AuthenticationManager = {
} }
) // end register user ) // end register user
} else { } else {
AuthenticationManager.login(user, "randomPass", callback) AuthenticationManager.login(user1, "randomPass", callback)
} }
}, },
@ -259,7 +239,9 @@ const AuthenticationManager = {
bcrypt.compare(password, user.hashedPassword, function (error, match) { bcrypt.compare(password, user.hashedPassword, function (error, match) {
if (match) { if (match) {
console.log("Local user password match") console.log("Local user password match")
AuthenticationManager.login(user, password, callback) _metricsForSuccessfulPasswordMatch(password)
//callback(null, user, match)
AuthenticationManager.login(user, "randomPass", callback)
} else { } else {
console.log("Local user password mismatch, trying LDAP") console.log("Local user password mismatch, trying LDAP")
// check passwd against ldap // check passwd against ldap
@ -285,16 +267,6 @@ const AuthenticationManager = {
return null return null
}, },
validateEmail(email) {
// we use the emailadress from the ldap
// therefore we do not enforce checks here
const parsed = EmailHelper.parseEmail(email)
//if (!parsed) {
// return new InvalidEmailError({ message: 'email not valid' })
//}
return null
},
async ldapAuth( async ldapAuth(
query, query,
password, password,
@ -302,9 +274,16 @@ const AuthenticationManager = {
callback, callback,
user user
) { ) {
const client = new Client({ const client = fs.existsSync(process.env.LDAP_SERVER_CACERT)
url: process.env.LDAP_SERVER, ? new Client({
}) url: process.env.LDAP_SERVER,
tlsOptions: {
ca: [fs.readFileSync(process.env.LDAP_SERVER_CACERT)],
},
})
: new Client({
url: process.env.LDAP_SERVER,
})
const ldap_reader = process.env.LDAP_BIND_USER const ldap_reader = process.env.LDAP_BIND_USER
const ldap_reader_pass = process.env.LDAP_BIND_PW const ldap_reader_pass = process.env.LDAP_BIND_PW
@ -450,6 +429,14 @@ const AuthenticationManager = {
}, },
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
validateEmail(email) {
const parsed = EmailHelper.parseEmail(email)
if (!parsed) {
return new InvalidEmailError({ message: 'email not valid' })
}
return null
},
// validates a password based on a similar set of rules to `complexPassword.js` on the frontend // validates a password based on a similar set of rules to `complexPassword.js` on the frontend
// note that `passfield.js` enforces more rules than this, but these are the most commonly set. // note that `passfield.js` enforces more rules than this, but these are the most commonly set.
// returns null on success, or an error object. // returns null on success, or an error object.
@ -611,6 +598,28 @@ const AuthenticationManager = {
}, },
_setUserPasswordInMongo(user, password, callback) { _setUserPasswordInMongo(user, password, callback) {
this.hashPassword(password, function (error, hash) {
if (error) {
return callback(error)
}
db.users.updateOne(
{ _id: ObjectId(user._id.toString()) },
{
$set: {
hashedPassword: hash,
},
$unset: {
password: true,
},
},
function (updateError, result) {
if (updateError) {
return callback(updateError)
}
_checkWriteResult(result, callback)
}
)
})
}, },
_passwordCharactersAreValid(password) { _passwordCharactersAreValid(password) {