Merge pull request #6614 from overleaf/jpa-msm-separate-admin-app

[misc] move admin capability from www. to admin. subdomain

GitOrigin-RevId: e0daeacf3c06b856ffb9fd35dce76e71f14e8459
This commit is contained in:
Jakob Ackermann
2022-04-05 12:18:24 +00:00
committed by Copybot
parent c96fbc526e
commit e82a053c85
25 changed files with 223 additions and 20 deletions
@@ -0,0 +1,64 @@
const Settings = require('@overleaf/settings')
const { expect } = require('chai')
const User = require('./helpers/User').promises
describe('AdminOnlyLogin', function () {
let adminUser, regularUser
const flagBefore = Settings.adminOnlyLogin
after(function () {
Settings.adminOnlyLogin = flagBefore
})
beforeEach('create admin user', async function () {
adminUser = new User()
await adminUser.ensureUserExists()
await adminUser.ensureAdmin()
})
beforeEach('create regular user', async function () {
regularUser = new User()
await regularUser.ensureUserExists()
})
async function expectCanLogin(user) {
const response = await user.login()
expect(response.statusCode).to.equal(200)
expect(response.body).to.deep.equal({ redir: '/project' })
}
async function expectRejectedLogin(user) {
const response = await user.login()
expect(response.statusCode).to.equal(403)
expect(response.body).to.deep.equal({
message: { type: 'error', text: 'Admin only panel' },
})
}
describe('adminOnlyLogin=true', function () {
beforeEach(function () {
Settings.adminOnlyLogin = true
})
it('should allow the admin user to login', async function () {
await expectCanLogin(adminUser)
})
it('should block a regular user from login', async function () {
await expectRejectedLogin(regularUser)
})
})
describe('adminOnlyLogin=false', function () {
beforeEach(function () {
Settings.adminOnlyLogin = false
})
it('should allow the admin user to login', async function () {
await expectCanLogin(adminUser)
})
it('should allow a regular user to login', async function () {
await expectCanLogin(regularUser)
})
})
})
@@ -0,0 +1,62 @@
const Settings = require('@overleaf/settings')
const { expect } = require('chai')
const User = require('./helpers/User').promises
describe('AdminPrivilegeAvailable', function () {
let adminUser
const flagBefore = Settings.adminPrivilegeAvailable
after(function () {
Settings.adminPrivilegeAvailable = flagBefore
})
beforeEach('create admin user', async function () {
adminUser = new User()
await adminUser.ensureUserExists()
await adminUser.ensureAdmin()
await adminUser.login()
})
let projectIdOwned, otherUsersProjectId
beforeEach('create owned project', async function () {
projectIdOwned = await adminUser.createProject('owned project')
})
beforeEach('create other user and project', async function () {
const otherUser = new User()
await otherUser.login()
otherUsersProjectId = await otherUser.createProject('other users project')
})
async function hasAccess(projectId) {
const { response } = await adminUser.doRequest(
'GET',
`/project/${projectId}`
)
return response.statusCode === 200
}
describe('adminPrivilegeAvailable=true', function () {
beforeEach(function () {
Settings.adminPrivilegeAvailable = true
})
it('should grant the admin access to owned project', async function () {
expect(await hasAccess(projectIdOwned)).to.equal(true)
})
it('should grant the admin access to non-owned project', async function () {
expect(await hasAccess(otherUsersProjectId)).to.equal(true)
})
})
describe('adminPrivilegeAvailable=false', function () {
beforeEach(function () {
Settings.adminPrivilegeAvailable = false
})
it('should grant the admin access to owned project', async function () {
expect(await hasAccess(projectIdOwned)).to.equal(true)
})
it('should block the admin from non-owned project', async function () {
expect(await hasAccess(otherUsersProjectId)).to.equal(false)
})
})
})
@@ -33,6 +33,10 @@ describe('AuthenticationController', function () {
this.AuthenticationController = SandboxedModule.require(modulePath, {
requires: {
'../Helpers/AdminAuthorizationHelper': (this.AdminAuthorizationHelper =
{
hasAdminAccess: sinon.stub().returns(false),
}),
'./AuthenticationErrors': AuthenticationErrors,
'../User/UserAuditLogHandler': (this.UserAuditLogHandler = {
addEntry: sinon.stub().yields(null),
@@ -158,6 +162,7 @@ describe('AuthenticationController', function () {
this.SessionManager.getSessionUser = sinon
.stub()
.returns({ isAdmin: true })
this.AdminAuthorizationHelper.hasAdminAccess.returns(true)
this.AuthenticationController.validateAdmin(this.req, this.res, err => {
this.SessionManager.getSessionUser.called.should.equal(true)
expect(err).to.exist
@@ -167,6 +172,7 @@ describe('AuthenticationController', function () {
it('should block an admin with a bad domain', function (done) {
this.SessionManager.getSessionUser = sinon.stub().returns(this.badAdmin)
this.AdminAuthorizationHelper.hasAdminAccess.returns(true)
this.AuthenticationController.validateAdmin(this.req, this.res, err => {
this.SessionManager.getSessionUser.called.should.equal(true)
expect(err).to.exist
@@ -54,7 +54,10 @@ describe('AuthorizationManager', function () {
'../Project/ProjectGetter': this.ProjectGetter,
'../../models/User': { User: this.User },
'../TokenAccess/TokenAccessHandler': this.TokenAccessHandler,
'@overleaf/settings': { passwordStrengthOptions: {} },
'@overleaf/settings': {
passwordStrengthOptions: {},
adminPrivilegeAvailable: true,
},
},
})
})
@@ -1,4 +1,5 @@
const SandboxedModule = require('sandboxed-module')
const sinon = require('sinon')
const { expect } = require('chai')
const modulePath = '../../../../app/src/Features/Helpers/AuthorizationHelper'
@@ -6,6 +7,9 @@ describe('AuthorizationHelper', function () {
beforeEach(function () {
this.AuthorizationHelper = SandboxedModule.require(modulePath, {
requires: {
'./AdminAuthorizationHelper': (this.AdminAuthorizationHelper = {
hasAdminAccess: sinon.stub().returns(false),
}),
'../../models/User': {
UserSchema: {
obj: {
@@ -38,11 +42,13 @@ describe('AuthorizationHelper', function () {
it('with admin user', function () {
const user = { isAdmin: true }
this.AdminAuthorizationHelper.hasAdminAccess.returns(true)
expect(this.AuthorizationHelper.hasAnyStaffAccess(user)).to.be.true
})
it('with staff user', function () {
const user = { staffAccess: { adminMetrics: true, somethingElse: false } }
this.AdminAuthorizationHelper.hasAdminAccess.returns(true)
expect(this.AuthorizationHelper.hasAnyStaffAccess(user)).to.be.true
})
@@ -22,6 +22,7 @@ describe('ProjectHelper', function () {
}
this.Settings = {
adminPrivilegeAvailable: true,
allowedImageNames: [
{ imageName: 'texlive-full:2018.1', imageDesc: 'TeX Live 2018' },
{ imageName: 'texlive-full:2019.1', imageDesc: 'TeX Live 2019' },