aboutsummaryrefslogtreecommitdiff
path: root/overleaf-mods/overleaf-ldap-oauth2/ldap-overleaf-sl/sharelatex/authmanager.diff
diff options
context:
space:
mode:
Diffstat (limited to 'overleaf-mods/overleaf-ldap-oauth2/ldap-overleaf-sl/sharelatex/authmanager.diff')
-rw-r--r--overleaf-mods/overleaf-ldap-oauth2/ldap-overleaf-sl/sharelatex/authmanager.diff297
1 files changed, 297 insertions, 0 deletions
diff --git a/overleaf-mods/overleaf-ldap-oauth2/ldap-overleaf-sl/sharelatex/authmanager.diff b/overleaf-mods/overleaf-ldap-oauth2/ldap-overleaf-sl/sharelatex/authmanager.diff
new file mode 100644
index 0000000..841804d
--- /dev/null
+++ b/overleaf-mods/overleaf-ldap-oauth2/ldap-overleaf-sl/sharelatex/authmanager.diff
@@ -0,0 +1,297 @@
+12,13d11
+< const { Client } = require('ldapts');
+< const ldapEscape = require('ldap-escape');
+34,92c32,36
+< //console.log("Begining:" + JSON.stringify(query))
+< AuthenticationManager.authUserObj(error, user, query, password, callback)
+< })
+< },
+< //login with any password
+< login(user, password, callback) {
+< AuthenticationManager.checkRounds(
+< user,
+< user.hashedPassword,
+< password,
+< function (err) {
+< if (err) {
+< return callback(err)
+< }
+< callback(null, user)
+< HaveIBeenPwned.checkPasswordForReuseInBackground(password)
+< }
+< )
+< },
+<
+< //oauth2
+< createUserIfNotExist(oauth_user, callback) {
+< const query = {
+< //name: ZHANG San
+< email: oauth_user.email
+< };
+< User.findOne(query, (error, user) => {
+< if ((!user || !user.hashedPassword)) {
+< //create random pass for local userdb, does not get checked for ldap users during login
+< let pass = require("crypto").randomBytes(32).toString("hex")
+< const userRegHand = require('../User/UserRegistrationHandler.js')
+< userRegHand.registerNewUser({
+< email: query.email,
+< first_name: oauth_user.given_name,
+< last_name: oauth_user.family_name,
+< password: pass
+< },
+< function (error, user) {
+< if (error) {
+< return callback(error, null);
+< }
+< user.admin = false
+< user.emails[0].confirmedAt = Date.now()
+< user.save()
+< console.log("user %s added to local library", query.email)
+< User.findOne(query, (error, user) => {
+< if (error) {
+< return callback(error, null);
+< }
+< if (user && user.hashedPassword) {
+< return callback(null, user);
+< } else {
+< return callback("Unknown error", null);
+< }
+< }
+< )
+< })
+< } else {
+< return callback(null, user);
+---
+> if (error) {
+> return callback(error)
+> }
+> if (!user || !user.hashedPassword) {
+> return callback(null, null)
+94,138d37
+< });
+< },
+<
+< //LDAP
+< createIfNotExistAndLogin(query, user, callback, uid, firstname, lastname, mail, isAdmin) {
+< if (!user) {
+< //console.log("Creating User:" + JSON.stringify(query))
+< //create random pass for local userdb, does not get checked for ldap users during login
+< let pass = require("crypto").randomBytes(32).toString("hex")
+< //console.log("Creating User:" + JSON.stringify(query) + "Random Pass" + pass)
+<
+< const userRegHand = require('../User/UserRegistrationHandler.js')
+< userRegHand.registerNewUser({
+< email: mail,
+< first_name: firstname,
+< last_name: lastname,
+< password: pass
+< },
+< function (error, user) {
+< if (error) {
+< console.log(error)
+< }
+< user.email = mail
+< user.isAdmin = isAdmin
+< user.emails[0].confirmedAt = Date.now()
+< user.save()
+< //console.log("user %s added to local library: ", mail)
+< User.findOne(query, (error, user) => {
+< if (error) {
+< console.log(error)
+< }
+< if (user && user.hashedPassword) {
+< AuthenticationManager.login(user, "randomPass", callback)
+< }
+< })
+< }) // end register user
+< } else {
+< AuthenticationManager.login(user, "randomPass", callback)
+< }
+< },
+<
+< authUserObj(error, user, query, password, callback) {
+< if ( process.env.ALLOW_EMAIL_LOGIN && user && user.hashedPassword) {
+< console.log("email login for existing user " + query.email)
+< // check passwd against local db
+140,146c39,40
+< if (match) {
+< console.log("Local user password match")
+< AuthenticationManager.login(user, password, callback)
+< } else {
+< console.log("Local user password mismatch, trying LDAP")
+< // check passwd against ldap
+< AuthenticationManager.ldapAuth(query, password, AuthenticationManager.createIfNotExistAndLogin, callback, user)
+---
+> if (error) {
+> return callback(error)
+147a42,73
+> const update = { $inc: { loginEpoch: 1 } }
+> if (!match) {
+> update.$set = { lastFailedLogin: new Date() }
+> }
+> User.updateOne(
+> { _id: user._id, loginEpoch: user.loginEpoch },
+> update,
+> {},
+> (err, result) => {
+> if (err) {
+> return callback(err)
+> }
+> if (result.nModified !== 1) {
+> return callback(new ParallelLoginError())
+> }
+> if (!match) {
+> return callback(null, null)
+> }
+> AuthenticationManager.checkRounds(
+> user,
+> user.hashedPassword,
+> password,
+> function (err) {
+> if (err) {
+> return callback(err)
+> }
+> callback(null, user)
+> HaveIBeenPwned.checkPasswordForReuseInBackground(password)
+> }
+> )
+> }
+> )
+149,153c75
+< } else {
+< // No local passwd check user has to be in ldap and use ldap credentials
+< AuthenticationManager.ldapAuth(query, password, AuthenticationManager.createIfNotExistAndLogin, callback, user)
+< }
+< return null
+---
+> })
+157,158d78
+< // we use the emailadress from the ldap
+< // therefore we do not enforce checks here
+160,162c80,82
+< //if (!parsed) {
+< // return new InvalidEmailError({ message: 'email not valid' })
+< //}
+---
+> if (!parsed) {
+> return new InvalidEmailError({ message: 'email not valid' })
+> }
+320,437d239
+<
+<
+< async ldapAuth(query, password, onSuccessCreateUserIfNotExistent, callback, user) {
+< const client = new Client({
+< url: process.env.LDAP_SERVER,
+< });
+<
+< const ldap_reader = process.env.LDAP_BIND_USER
+< const ldap_reader_pass = process.env.LDAP_BIND_PW
+< const ldap_base = process.env.LDAP_BASE
+<
+< var mail = query.email
+< var uid = query.email.split('@')[0]
+< var firstname = ""
+< var lastname = ""
+< var isAdmin = false
+< var userDn = ""
+<
+< //replace all appearences of %u with uid and all %m with mail:
+< const replacerUid = new RegExp("%u", "g")
+< const replacerMail = new RegExp("%m","g")
+< const filterstr = process.env.LDAP_USER_FILTER.replace(replacerUid, ldapEscape.filter`${uid}`).replace(replacerMail, ldapEscape.filter`${mail}`) //replace all appearances
+< // check bind
+< try {
+< if(process.env.LDAP_BINDDN){ //try to bind directly with the user trying to log in
+< userDn = process.env.LDAP_BINDDN.replace(replacerUid,ldapEscape.filter`${uid}`).replace(replacerMail, ldapEscape.filter`${mail}`);
+< await client.bind(userDn,password);
+< }else{// use fixed bind user
+< await client.bind(ldap_reader, ldap_reader_pass);
+< }
+< } catch (ex) {
+< if(process.env.LDAP_BINDDN){
+< console.log("Could not bind user: " + userDn);
+< }else{
+< console.log("Could not bind LDAP reader: " + ldap_reader + " err: " + String(ex))
+< }
+< return callback(null, null)
+< }
+<
+< // get user data
+< try {
+< const {searchEntries, searchRef,} = await client.search(ldap_base, {
+< scope: 'sub',
+< filter: filterstr ,
+< });
+< await searchEntries
+< console.log(JSON.stringify(searchEntries))
+< if (searchEntries[0]) {
+< mail = searchEntries[0].mail
+< uid = searchEntries[0].uid
+< firstname = searchEntries[0].givenName
+< lastname = searchEntries[0].sn
+< if(!process.env.LDAP_BINDDN){ //dn is already correctly assembled
+< userDn = searchEntries[0].dn
+< }
+< console.log("Found user: " + mail + " Name: " + firstname + " " + lastname + " DN: " + userDn)
+< }
+< } catch (ex) {
+< console.log("An Error occured while getting user data during ldapsearch: " + String(ex))
+< await client.unbind();
+< return callback(null, null)
+< }
+<
+< try {
+< // if admin filter is set - only set admin for user in ldap group
+< // does not matter - admin is deactivated: managed through ldap
+< if (process.env.LDAP_ADMIN_GROUP_FILTER) {
+< const adminfilter = process.env.LDAP_ADMIN_GROUP_FILTER.replace(replacerUid, ldapEscape.filter`${uid}`).replace(replacerMail, ldapEscape.filter`${mail}`)
+< adminEntry = await client.search(ldap_base, {
+< scope: 'sub',
+< filter: adminfilter,
+< });
+< await adminEntry;
+< //console.log("Admin Search response:" + JSON.stringify(adminEntry.searchEntries))
+< if (adminEntry.searchEntries[0]) {
+< console.log("is Admin")
+< isAdmin=true;
+< }
+< }
+< } catch (ex) {
+< console.log("An Error occured while checking for admin rights - setting admin rights to false: " + String(ex))
+< isAdmin = false;
+< } finally {
+< await client.unbind();
+< }
+< if (mail == "" || userDn == "") {
+< console.log("Mail / userDn not set - exit. This should not happen - please set mail-entry in ldap.")
+< return callback(null, null)
+< }
+<
+< if(!process.env.BINDDN){//since we used a fixed bind user to obtain the correct userDn we need to bind again to authenticate
+< try {
+< await client.bind(userDn, password);
+< } catch (ex) {
+< console.log("Could not bind User: " + userDn + " err: " + String(ex))
+< return callback(null, null)
+< } finally{
+< await client.unbind()
+< }
+< }
+< //console.log("Logging in user: " + mail + " Name: " + firstname + " " + lastname + " isAdmin: " + String(isAdmin))
+< // we are authenticated now let's set the query to the correct mail from ldap
+< query.email = mail
+< User.findOne(query, (error, user) => {
+< if (error) {
+< console.log(error)
+< }
+< if (user && user.hashedPassword) {
+< //console.log("******************** LOGIN ******************")
+< AuthenticationManager.login(user, "randomPass", callback)
+< } else {
+< onSuccessCreateUserIfNotExistent(query, user, callback, uid, firstname, lastname, mail, isAdmin)
+< }
+< })
+< }
+<
+<
+<