Diff and patch modification (close #34)
This commit is contained in:
305
ldap-overleaf-sl/sharelatex_diff/AuthenticationManager.js.diff
Normal file
305
ldap-overleaf-sl/sharelatex_diff/AuthenticationManager.js.diff
Normal file
@@ -0,0 +1,305 @@
|
||||
19a20,25
|
||||
> // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
> const fs = require("fs")
|
||||
> const { Client } = require("ldapts")
|
||||
> const ldapEscape = require("ldap-escape")
|
||||
> // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
>
|
||||
84a91,100
|
||||
> // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
> _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)
|
||||
> })
|
||||
> },
|
||||
> // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
>
|
||||
90c106,108
|
||||
< AuthenticationManager._checkUserPassword(
|
||||
---
|
||||
> // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
> AuthenticationManager._checkUserPassword2(
|
||||
> // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
153a172,451
|
||||
>
|
||||
> // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
> /**
|
||||
> * login with any password
|
||||
> */
|
||||
> login(user, password, callback) {
|
||||
> callback(null, user, true)
|
||||
> },
|
||||
>
|
||||
> createIfNotFoundAndLogin(
|
||||
> query,
|
||||
> callback,
|
||||
> uid,
|
||||
> firstname,
|
||||
> lastname,
|
||||
> mail,
|
||||
> isAdmin
|
||||
> ) {
|
||||
> User.findOne(query, (error, user) => {
|
||||
> if (error) {
|
||||
> console.log(error)
|
||||
> }
|
||||
>
|
||||
> AuthenticationManager.createIfNotExistAndLogin(
|
||||
> query,
|
||||
> user,
|
||||
> callback,
|
||||
> uid,
|
||||
> firstname,
|
||||
> lastname,
|
||||
> mail,
|
||||
> isAdmin
|
||||
> )
|
||||
> })
|
||||
> },
|
||||
>
|
||||
> createIfNotExistAndLogin(
|
||||
> query,
|
||||
> user,
|
||||
> callback,
|
||||
> uid,
|
||||
> firstname,
|
||||
> lastname,
|
||||
> mail,
|
||||
> isAdmin
|
||||
> ) {
|
||||
> if (!user) {
|
||||
> //create random pass for local userdb, does not get checked for ldap users during login
|
||||
> const pass = require("crypto").randomBytes(32).toString("hex")
|
||||
> console.log('Creating User', { mail, uid, firstname, lastname, isAdmin, pass })
|
||||
>
|
||||
> const userRegHand = require("../User/UserRegistrationHandler.js")
|
||||
> userRegHand.registerNewUser(
|
||||
> {
|
||||
> email: mail,
|
||||
> first_name: firstname,
|
||||
> last_name: lastname,
|
||||
> password: pass,
|
||||
> },
|
||||
> function (error, user, setNewPasswordUrl) {
|
||||
> 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 {
|
||||
> console.log('User exists', { mail })
|
||||
> 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
|
||||
> bcrypt.compare(password, user.hashedPassword, function (error, match) {
|
||||
> if (match) {
|
||||
> console.log("Local user password match")
|
||||
> _metricsForSuccessfulPasswordMatch(password)
|
||||
> //callback(null, user, match)
|
||||
> AuthenticationManager.login(user, "randomPass", callback)
|
||||
> } else {
|
||||
> console.log("Local user password mismatch, trying LDAP")
|
||||
> // check passwd against ldap
|
||||
> AuthenticationManager.ldapAuth(
|
||||
> query,
|
||||
> password,
|
||||
> AuthenticationManager.createIfNotExistAndLogin,
|
||||
> callback,
|
||||
> user
|
||||
> )
|
||||
> }
|
||||
> })
|
||||
> } 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
|
||||
> },
|
||||
>
|
||||
> async ldapAuth(
|
||||
> query,
|
||||
> password,
|
||||
> onSuccessCreateUserIfNotExistent,
|
||||
> callback,
|
||||
> user
|
||||
> ) {
|
||||
> const client = fs.existsSync(process.env.LDAP_SERVER_CACERT)
|
||||
> ? 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_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
|
||||
> )
|
||||
> }
|
||||
> })
|
||||
> },
|
||||
> // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
Reference in New Issue
Block a user