From d59b154f076f1cd093b29b437443575c384a61bd Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Thu, 31 Mar 2022 11:35:16 +0100 Subject: [PATCH] Merge pull request #6712 from overleaf/jpa-redirect-token-access [web] redirect admin users from token access gateway to admin panel GitOrigin-RevId: b39c9b4bcad5d376b720a6718df7ef01cd89938f --- .../Helpers/AdminAuthorizationHelper.js | 7 ++++ .../TokenAccess/TokenAccessController.js | 9 +++++ services/web/docker-compose.common.env | 1 + .../src/AdminPrivilegeAvailableTests.js | 39 +++++++++++++++++-- 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/services/web/app/src/Features/Helpers/AdminAuthorizationHelper.js b/services/web/app/src/Features/Helpers/AdminAuthorizationHelper.js index bc47dd98ba..3330d1f1b8 100644 --- a/services/web/app/src/Features/Helpers/AdminAuthorizationHelper.js +++ b/services/web/app/src/Features/Helpers/AdminAuthorizationHelper.js @@ -2,6 +2,7 @@ const Settings = require('@overleaf/settings') module.exports = { hasAdminAccess, + shouldRedirectToAdminPanel, } function hasAdminAccess(user) { @@ -9,3 +10,9 @@ function hasAdminAccess(user) { if (!user) return false return Boolean(user.isAdmin) } + +function shouldRedirectToAdminPanel(user) { + if (Settings.adminPrivilegeAvailable) return false + if (!user) return false + return Boolean(user.isAdmin) +} diff --git a/services/web/app/src/Features/TokenAccess/TokenAccessController.js b/services/web/app/src/Features/TokenAccess/TokenAccessController.js index 1365bdc812..e57f1b5c5e 100644 --- a/services/web/app/src/Features/TokenAccess/TokenAccessController.js +++ b/services/web/app/src/Features/TokenAccess/TokenAccessController.js @@ -8,6 +8,9 @@ const OError = require('@overleaf/o-error') const { expressify } = require('../../util/promises') const AuthorizationManager = require('../Authorization/AuthorizationManager') const PrivilegeLevels = require('../Authorization/PrivilegeLevels') +const { + shouldRedirectToAdminPanel, +} = require('../Helpers/AdminAuthorizationHelper') const orderedPrivilegeLevels = [ PrivilegeLevels.NONE, @@ -83,6 +86,12 @@ async function tokenAccessPage(req, res, next) { if (!TokenAccessHandler.isValidToken(token)) { return next(new Errors.NotFoundError()) } + if (shouldRedirectToAdminPanel(SessionManager.getSessionUser(req.session))) { + const path = TokenAccessHandler.isReadOnlyToken(token) + ? `/read/${token}` + : `/${token}` + return res.redirect(settings.adminUrl + path) + } try { if (TokenAccessHandler.isReadOnlyToken(token)) { const docPublishedInfo = diff --git a/services/web/docker-compose.common.env b/services/web/docker-compose.common.env index e9e50ab7d8..7190a8e525 100644 --- a/services/web/docker-compose.common.env +++ b/services/web/docker-compose.common.env @@ -10,6 +10,7 @@ NODE_ENV=test NODE_OPTIONS=--unhandled-rejections=strict LOCK_MANAGER_MAX_LOCK_WAIT_TIME=30000 COOKIE_DOMAIN=.overleaf.test +ADMIN_URL=http://admin.overleaf.test PUBLIC_URL=http://www.overleaf.test:3000 HTTP_TEST_HOST=www.overleaf.test OT_JWT_AUTH_KEY=very secret key diff --git a/services/web/test/acceptance/src/AdminPrivilegeAvailableTests.js b/services/web/test/acceptance/src/AdminPrivilegeAvailableTests.js index 6673551fb5..8924965ed0 100644 --- a/services/web/test/acceptance/src/AdminPrivilegeAvailableTests.js +++ b/services/web/test/acceptance/src/AdminPrivilegeAvailableTests.js @@ -3,7 +3,7 @@ const { expect } = require('chai') const User = require('./helpers/User').promises describe('AdminPrivilegeAvailable', function () { - let adminUser + let adminUser, otherUser const flagBefore = Settings.adminPrivilegeAvailable after(function () { Settings.adminPrivilegeAvailable = flagBefore @@ -16,16 +16,21 @@ describe('AdminPrivilegeAvailable', function () { await adminUser.login() }) - let projectIdOwned, otherUsersProjectId + let projectIdOwned, otherUsersProjectId, otherUsersProjectTokenAccessURL beforeEach('create owned project', async function () { projectIdOwned = await adminUser.createProject('owned project') }) beforeEach('create other user and project', async function () { - const otherUser = new User() + otherUser = new User() await otherUser.login() otherUsersProjectId = await otherUser.createProject('other users project') + await otherUser.makeTokenBased(otherUsersProjectId) + const { + tokens: { readOnly: readOnlyToken }, + } = await otherUser.getProject(otherUsersProjectId) + otherUsersProjectTokenAccessURL = `/read/${readOnlyToken}` }) async function hasAccess(projectId) { @@ -36,6 +41,15 @@ describe('AdminPrivilegeAvailable', function () { return response.statusCode === 200 } + async function displayTokenAccessPage(user) { + const { response } = await user.doRequest( + 'GET', + otherUsersProjectTokenAccessURL + ) + expect(response.statusCode).to.equal(200) + expect(response.body).to.include(otherUsersProjectTokenAccessURL) + } + describe('adminPrivilegeAvailable=true', function () { beforeEach(function () { Settings.adminPrivilegeAvailable = true @@ -46,6 +60,12 @@ describe('AdminPrivilegeAvailable', function () { it('should grant the admin access to non-owned project', async function () { expect(await hasAccess(otherUsersProjectId)).to.equal(true) }) + it('should display token access page for admin', async function () { + await displayTokenAccessPage(adminUser) + }) + it('should display token access page for regular user', async function () { + await displayTokenAccessPage(otherUser) + }) }) describe('adminPrivilegeAvailable=false', function () { @@ -58,5 +78,18 @@ describe('AdminPrivilegeAvailable', function () { it('should block the admin from non-owned project', async function () { expect(await hasAccess(otherUsersProjectId)).to.equal(false) }) + it('should redirect a token access request to admin panel', async function () { + const { response } = await adminUser.doRequest( + 'GET', + otherUsersProjectTokenAccessURL + ) + expect(response.statusCode).to.equal(302) + expect(response.headers.location).to.equal( + Settings.adminUrl + otherUsersProjectTokenAccessURL + ) + }) + it('should display token access page for regular user', async function () { + await displayTokenAccessPage(otherUser) + }) }) })