mirror of
https://git.unistra.fr/aius/root/ldap-overleaf-sl.git
synced 2025-05-04 19:55:26 +02:00
Fix bugs
This commit is contained in:
parent
242183d601
commit
f53790c452
5 changed files with 110 additions and 63 deletions
|
@ -43,12 +43,9 @@ COPY sharelatex/navbar.pug /overleaf/services/web/app/views/layout/
|
||||||
COPY sharelatex/admin-index.pug /overleaf/services/web/app/views/admin/index.pug
|
COPY sharelatex/admin-index.pug /overleaf/services/web/app/views/admin/index.pug
|
||||||
COPY sharelatex/admin-sysadmin.pug /tmp/admin-sysadmin.pug
|
COPY sharelatex/admin-sysadmin.pug /tmp/admin-sysadmin.pug
|
||||||
|
|
||||||
## instead of copying the login.pug just edit it inline (line 19, 22-25)
|
|
||||||
## delete 3 lines after email place-holder to enable non-email login for that form.
|
|
||||||
RUN sed -iE '/type=.*email.*/d' /overleaf/services/web/app/views/user/login.pug && \
|
|
||||||
## comment out this line to prevent sed accidently remove the brackets of the email(username) field
|
## comment out this line to prevent sed accidently remove the brackets of the email(username) field
|
||||||
# sed -iE '/email@example.com/{n;N;N;d}' /overleaf/services/web/app/views/user/login.pug && \
|
# sed -iE '/email@example.com/{n;N;N;d}' /overleaf/services/web/app/views/user/login.pug && \
|
||||||
sed -iE "s/email@example.com/${login_text:-user}/g" /overleaf/services/web/app/views/user/login.pug && \
|
RUN sed -iE "s/email@example.com/${login_text:-user}/g" /overleaf/services/web/app/views/user/login.pug && \
|
||||||
## Collaboration settings display (share project placeholder) | edit line 146
|
## Collaboration settings display (share project placeholder) | edit line 146
|
||||||
## share.pug file was removed in later versions
|
## share.pug file was removed in later versions
|
||||||
# sed -iE "s%placeholder=.*$%placeholder=\"${collab_text}\"%g" /overleaf/services/web/app/views/project/editor/share.pug && \
|
# sed -iE "s%placeholder=.*$%placeholder=\"${collab_text}\"%g" /overleaf/services/web/app/views/project/editor/share.pug && \
|
||||||
|
|
|
@ -275,81 +275,79 @@ const AuthenticationController = {
|
||||||
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
oauth2Redirect(req, res, next) {
|
oauth2Redirect(req, res, next) {
|
||||||
const redirectURI = encodeURIComponent(`${process.env.SHARELATEX_SITE_URL}/oauth/callback`)
|
const redirectURI = encodeURIComponent(`${process.env.SHARELATEX_SITE_URL}/oauth/callback`)
|
||||||
const next = (
|
const authURL = (
|
||||||
process.env.OAUTH2_AUTHORIZATION_URL
|
process.env.OAUTH2_AUTHORIZATION_URL
|
||||||
+ `?response_type=code`
|
+ `?response_type=code`
|
||||||
+ `&client_id=${process.env.OAUTH2_CLIENT_ID}`
|
+ `&client_id=${process.env.OAUTH2_CLIENT_ID}`
|
||||||
+ `&redirect_uri=${redirectURI}`
|
+ `&redirect_uri=${redirectURI}`
|
||||||
+ `&scope=${process.env.OAUTH2_SCOPE ?? ""}` // TODO: state
|
+ `&scope=${process.env.OAUTH2_SCOPE ?? ""}` // TODO: state
|
||||||
)
|
)
|
||||||
res.redirect(next)
|
res.redirect(authURL)
|
||||||
},
|
},
|
||||||
|
|
||||||
async oauth2Callback(req, res, next) {
|
async oauth2Callback(req, res, next) {
|
||||||
try {
|
try {
|
||||||
const redirectURI = encodeURIComponent(`${process.env.SHARELATEX_SITE_URL}/oauth/callback`);
|
console.log("OAuth2 code", req.query.code)
|
||||||
const tokenResponse = await fetch(process.env.OAUTH2_TOKEN_URL, {
|
const tokenResponse = await fetch(process.env.OAUTH2_TOKEN_URL, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
"Accept": "application/json",
|
||||||
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
grant_type: "authorization_code",
|
grant_type: "authorization_code",
|
||||||
client_id: process.env.OAUTH2_CLIENT_ID,
|
client_id: process.env.OAUTH2_CLIENT_ID,
|
||||||
client_secret: process.env.OAUTH2_CLIENT_SECRET,
|
client_secret: process.env.OAUTH2_CLIENT_SECRET,
|
||||||
code: req.query.code,
|
code: req.query.code,
|
||||||
redirect_uri: redirectURI,
|
redirect_uri: `${process.env.SHARELATEX_SITE_URL}/oauth/callback`,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const tokenData = await tokenResponse.json()
|
const tokenData = await tokenResponse.json()
|
||||||
console.log("OAuth2 respond", JSON.stringify(tokenData)) // TODO: remove
|
console.log("OAuth2 respond", JSON.stringify(tokenData))
|
||||||
console.log("OAuth2 accessToken", tokenData.access_token) // TODO: remove
|
|
||||||
|
|
||||||
const profileResponse = await fetch(process.env.OAUTH2_PROFILE_URL, {
|
const profileResponse = await fetch(process.env.OAUTH2_PROFILE_URL, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
|
"Accept": "application/json",
|
||||||
|
"Authorization": `Bearer ${tokenData.access_token}`,
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"Authorization": `Bearer ${tokenData.access_token}`
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const profile = await profileResponse.json()
|
const profile = await profileResponse.json()
|
||||||
console.log("OAuth2 user info", JSON.stringify(profile.data))
|
console.log("OAuth2 user profile", JSON.stringify(profile))
|
||||||
|
|
||||||
const email = profile[process.env.OAUTH2_USER_ATTR_EMAIL ?? "email"]
|
const email = profile[process.env.OAUTH2_USER_ATTR_EMAIL ?? "email"]
|
||||||
const uid = profile[process.env.OAUTH2_USER_ATTR_UID ?? "uid"]
|
const uid = profile[process.env.OAUTH2_USER_ATTR_UID ?? "uid"]
|
||||||
const firstname = profile?.[process.env.OAUTH2_USER_ATTR_FIRSTNAME] ?? email
|
const firstname = profile?.[process.env.OAUTH2_USER_ATTR_FIRSTNAME] ?? email
|
||||||
const lastname = profile?.[process.env.OAUTH2_USER_ATTR_LASTNAME] ?? ""
|
const lastname = process.env.OAUTH2_USER_ATTR_LASTNAME
|
||||||
|
? profile?.[process.env.OAUTH2_USER_ATTR_LASTNAME] ?? ""
|
||||||
const isAdmin = false // TODO: how to determine?
|
: ""
|
||||||
|
const isAdmin = process.env.OAUTH2_USER_ATTR_IS_ADMIN
|
||||||
|
? !!profile?.[process.env.OAUTH2_USER_ATTR_IS_ADMIN] ?? false
|
||||||
|
: false
|
||||||
|
|
||||||
const query = { email }
|
const query = { email }
|
||||||
User.findOne(query, (error, user) => {
|
const callback = (error, user) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
console.log(error)
|
res.json({message: error});
|
||||||
|
} else {
|
||||||
|
console.log("OAuth user", JSON.stringify(user));
|
||||||
|
AuthenticationController.finishLogin(user, req, res, next);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
const callback = (error, user) => {
|
AuthenticationManager.createIfNotFoundAndLogin(
|
||||||
if (error) {
|
query,
|
||||||
res.json({message: error});
|
callback,
|
||||||
} else {
|
uid,
|
||||||
// console.log("real_user: ", user);
|
firstname,
|
||||||
AuthenticationController.finishLogin(user, req, res, next);
|
lastname,
|
||||||
}
|
email,
|
||||||
}
|
isAdmin
|
||||||
AuthenticationManager.createIfNotExistAndLogin(
|
)
|
||||||
query,
|
|
||||||
user,
|
|
||||||
callback,
|
|
||||||
uid,
|
|
||||||
firstname,
|
|
||||||
lastname,
|
|
||||||
email,
|
|
||||||
isAdmin
|
|
||||||
)
|
|
||||||
})
|
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.log("Fails to access by OAuth2: " + String(e))
|
res.redirect("/login")
|
||||||
|
console.error("Fails to access by OAuth2: " + String(e))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
|
|
@ -184,6 +184,33 @@ const AuthenticationManager = {
|
||||||
callback(null, user, true)
|
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(
|
createIfNotExistAndLogin(
|
||||||
query,
|
query,
|
||||||
user,
|
user,
|
||||||
|
@ -195,10 +222,9 @@ const AuthenticationManager = {
|
||||||
isAdmin
|
isAdmin
|
||||||
) {
|
) {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
//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")
|
const pass = require("crypto").randomBytes(32).toString("hex")
|
||||||
//console.log('Creating User:' + JSON.stringify(query) + 'Random Pass' + pass)
|
console.log('Creating User', { mail, uid, firstname, lastname, isAdmin, pass })
|
||||||
|
|
||||||
const userRegHand = require("../User/UserRegistrationHandler.js")
|
const userRegHand = require("../User/UserRegistrationHandler.js")
|
||||||
userRegHand.registerNewUser(
|
userRegHand.registerNewUser(
|
||||||
|
@ -228,6 +254,7 @@ const AuthenticationManager = {
|
||||||
}
|
}
|
||||||
) // end register user
|
) // end register user
|
||||||
} else {
|
} else {
|
||||||
|
console.log('User exists', { mail })
|
||||||
AuthenticationManager.login(user, "randomPass", callback)
|
AuthenticationManager.login(user, "randomPass", callback)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,13 +16,21 @@ block content
|
||||||
input(name='_csrf', type='hidden', value=csrfToken)
|
input(name='_csrf', type='hidden', value=csrfToken)
|
||||||
+formMessages()
|
+formMessages()
|
||||||
.form-group
|
.form-group
|
||||||
|
//- >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
//- input.form-control(
|
||||||
|
//- type='email',
|
||||||
|
//- name='email',
|
||||||
|
//- required,
|
||||||
|
//- placeholder='email@example.com',
|
||||||
|
//- autofocus="true"
|
||||||
|
//- )
|
||||||
input.form-control(
|
input.form-control(
|
||||||
type='email',
|
|
||||||
name='email',
|
name='email',
|
||||||
required,
|
required,
|
||||||
placeholder='email@example.com',
|
placeholder='email@example.com',
|
||||||
autofocus="true"
|
autofocus="true"
|
||||||
)
|
)
|
||||||
|
//- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
.form-group
|
.form-group
|
||||||
input.form-control(
|
input.form-control(
|
||||||
type='password',
|
type='password',
|
||||||
|
@ -38,8 +46,8 @@ block content
|
||||||
span(data-ol-inflight="idle") #{translate("login")}
|
span(data-ol-inflight="idle") #{translate("login")}
|
||||||
span(hidden data-ol-inflight="pending") #{translate("logging_in")}…
|
span(hidden data-ol-inflight="pending") #{translate("logging_in")}…
|
||||||
a.pull-right(href='/user/password/reset') #{translate("forgot_your_password")}?
|
a.pull-right(href='/user/password/reset') #{translate("forgot_your_password")}?
|
||||||
//- >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
//- >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
.form-group.text-center(style="padding-top: 10px")
|
.form-group.text-center(style="padding-top: 10px")
|
||||||
a.btn-block.login-btn(href="/oauth/redirect" style='padding-left: 0px')
|
a.btn-block.login-btn(href="/oauth/redirect" style='padding-left: 0px')
|
||||||
| Log in via OAuth
|
| Log in via OAuth
|
||||||
//- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
//- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
* Modified from 6408d15
|
* Modified from bf92436
|
||||||
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ const UserInfoController = require('./Features/User/UserInfoController')
|
||||||
const UserController = require('./Features/User/UserController')
|
const UserController = require('./Features/User/UserController')
|
||||||
const UserEmailsController = require('./Features/User/UserEmailsController')
|
const UserEmailsController = require('./Features/User/UserEmailsController')
|
||||||
const UserPagesController = require('./Features/User/UserPagesController')
|
const UserPagesController = require('./Features/User/UserPagesController')
|
||||||
const TutorialController = require('./Features/Tutorial/TutorialController')
|
|
||||||
const DocumentController = require('./Features/Documents/DocumentController')
|
const DocumentController = require('./Features/Documents/DocumentController')
|
||||||
const CompileManager = require('./Features/Compile/CompileManager')
|
const CompileManager = require('./Features/Compile/CompileManager')
|
||||||
const CompileController = require('./Features/Compile/CompileController')
|
const CompileController = require('./Features/Compile/CompileController')
|
||||||
|
@ -105,6 +104,10 @@ const rateLimiters = {
|
||||||
points: 10,
|
points: 10,
|
||||||
duration: 60,
|
duration: 60,
|
||||||
}),
|
}),
|
||||||
|
confirmUniversityDomain: new RateLimiter('confirm-university-domain', {
|
||||||
|
points: 1,
|
||||||
|
duration: 60,
|
||||||
|
}),
|
||||||
createProject: new RateLimiter('create-project', {
|
createProject: new RateLimiter('create-project', {
|
||||||
points: 20,
|
points: 20,
|
||||||
duration: 60,
|
duration: 60,
|
||||||
|
@ -149,6 +152,10 @@ const rateLimiters = {
|
||||||
points: 30,
|
points: 30,
|
||||||
duration: 60,
|
duration: 60,
|
||||||
}),
|
}),
|
||||||
|
indexProjectReferences: new RateLimiter('index-project-references', {
|
||||||
|
points: 30,
|
||||||
|
duration: 60,
|
||||||
|
}),
|
||||||
miscOutputDownload: new RateLimiter('misc-output-download', {
|
miscOutputDownload: new RateLimiter('misc-output-download', {
|
||||||
points: 1000,
|
points: 1000,
|
||||||
duration: 60 * 60,
|
duration: 60 * 60,
|
||||||
|
@ -185,7 +192,7 @@ const rateLimiters = {
|
||||||
duration: 60,
|
duration: 60,
|
||||||
}),
|
}),
|
||||||
resendConfirmation: new RateLimiter('resend-confirmation', {
|
resendConfirmation: new RateLimiter('resend-confirmation', {
|
||||||
points: 1,
|
points: 10,
|
||||||
duration: 60,
|
duration: 60,
|
||||||
}),
|
}),
|
||||||
sendChatMessage: new RateLimiter('send-chat-message', {
|
sendChatMessage: new RateLimiter('send-chat-message', {
|
||||||
|
@ -256,12 +263,12 @@ function initialize(webRouter, privateApiRouter, publicApiRouter) {
|
||||||
AuthenticationController.addEndpointToLoginWhitelist('/register')
|
AuthenticationController.addEndpointToLoginWhitelist('/register')
|
||||||
}
|
}
|
||||||
|
|
||||||
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
webRouter.get('/oauth/redirect', AuthenticationController.oauth2Redirect)
|
webRouter.get('/oauth/redirect', AuthenticationController.oauth2Redirect)
|
||||||
webRouter.get('/oauth/callback', AuthenticationController.oauth2Callback)
|
webRouter.get('/oauth/callback', AuthenticationController.oauth2Callback)
|
||||||
AuthenticationController.addEndpointToLoginWhitelist('/oauth/redirect')
|
AuthenticationController.addEndpointToLoginWhitelist('/oauth/redirect')
|
||||||
AuthenticationController.addEndpointToLoginWhitelist('/oauth/callback')
|
AuthenticationController.addEndpointToLoginWhitelist('/oauth/callback')
|
||||||
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
|
||||||
EditorRouter.apply(webRouter, privateApiRouter)
|
EditorRouter.apply(webRouter, privateApiRouter)
|
||||||
CollaboratorsRouter.apply(webRouter, privateApiRouter)
|
CollaboratorsRouter.apply(webRouter, privateApiRouter)
|
||||||
|
@ -433,12 +440,6 @@ AuthenticationController.addEndpointToLoginWhitelist('/oauth/callback')
|
||||||
TpdsController.getQueues
|
TpdsController.getQueues
|
||||||
)
|
)
|
||||||
|
|
||||||
webRouter.post(
|
|
||||||
'/tutorial/:tutorialKey/complete',
|
|
||||||
AuthenticationController.requireLogin(),
|
|
||||||
TutorialController.completeTutorial
|
|
||||||
)
|
|
||||||
|
|
||||||
webRouter.get(
|
webRouter.get(
|
||||||
'/user/projects',
|
'/user/projects',
|
||||||
AuthenticationController.requireLogin(),
|
AuthenticationController.requireLogin(),
|
||||||
|
@ -734,6 +735,16 @@ AuthenticationController.addEndpointToLoginWhitelist('/oauth/callback')
|
||||||
AuthorizationMiddleware.ensureUserCanReadProject,
|
AuthorizationMiddleware.ensureUserCanReadProject,
|
||||||
HistoryController.proxyToHistoryApi
|
HistoryController.proxyToHistoryApi
|
||||||
)
|
)
|
||||||
|
webRouter.post(
|
||||||
|
'/project/:Project_id/doc/:doc_id/version/:version_id/restore',
|
||||||
|
AuthorizationMiddleware.ensureUserCanWriteProjectContent,
|
||||||
|
HistoryController.proxyToHistoryApi
|
||||||
|
)
|
||||||
|
webRouter.post(
|
||||||
|
'/project/:project_id/doc/:doc_id/restore',
|
||||||
|
AuthorizationMiddleware.ensureUserCanWriteProjectContent,
|
||||||
|
HistoryController.restoreDocFromDeletedDoc
|
||||||
|
)
|
||||||
webRouter.post(
|
webRouter.post(
|
||||||
'/project/:project_id/restore_file',
|
'/project/:project_id/restore_file',
|
||||||
AuthorizationMiddleware.ensureUserCanWriteProjectContent,
|
AuthorizationMiddleware.ensureUserCanWriteProjectContent,
|
||||||
|
@ -1082,6 +1093,12 @@ AuthenticationController.addEndpointToLoginWhitelist('/oauth/callback')
|
||||||
ChatController.sendMessage
|
ChatController.sendMessage
|
||||||
)
|
)
|
||||||
|
|
||||||
|
webRouter.post(
|
||||||
|
'/project/:Project_id/references/index',
|
||||||
|
AuthorizationMiddleware.ensureUserCanReadProject,
|
||||||
|
RateLimiterMiddleware.rateLimit(rateLimiters.indexProjectReferences),
|
||||||
|
ReferencesController.index
|
||||||
|
)
|
||||||
webRouter.post(
|
webRouter.post(
|
||||||
'/project/:Project_id/references/indexAll',
|
'/project/:Project_id/references/indexAll',
|
||||||
AuthorizationMiddleware.ensureUserCanReadProject,
|
AuthorizationMiddleware.ensureUserCanReadProject,
|
||||||
|
@ -1130,6 +1147,7 @@ AuthenticationController.addEndpointToLoginWhitelist('/oauth/callback')
|
||||||
)
|
)
|
||||||
publicApiRouter.post(
|
publicApiRouter.post(
|
||||||
'/api/institutions/confirm_university_domain',
|
'/api/institutions/confirm_university_domain',
|
||||||
|
RateLimiterMiddleware.rateLimit(rateLimiters.confirmUniversityDomain),
|
||||||
AuthenticationController.requirePrivateApiAuth(),
|
AuthenticationController.requirePrivateApiAuth(),
|
||||||
InstitutionsController.confirmDomain
|
InstitutionsController.confirmDomain
|
||||||
)
|
)
|
||||||
|
@ -1357,5 +1375,4 @@ AuthenticationController.addEndpointToLoginWhitelist('/oauth/callback')
|
||||||
webRouter.get('*', ErrorController.notFound)
|
webRouter.get('*', ErrorController.notFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = { initialize, rateLimiters }
|
module.exports = { initialize, rateLimiters }
|
Loading…
Add table
Reference in a new issue