mirror of
https://github.com/overleaf/overleaf.git
synced 2024-10-24 21:12:38 -04:00
196 lines
5.8 KiB
JavaScript
196 lines
5.8 KiB
JavaScript
|
const config = require('config')
|
||
|
const fetch = require('node-fetch')
|
||
|
const sinon = require('sinon')
|
||
|
const { expect } = require('chai')
|
||
|
|
||
|
const cleanup = require('../storage/support/cleanup')
|
||
|
const expectResponse = require('./support/expect_response')
|
||
|
const fixtures = require('../storage/support/fixtures')
|
||
|
const HTTPStatus = require('http-status')
|
||
|
const testServer = require('./support/test_server')
|
||
|
|
||
|
describe('auth', function () {
|
||
|
beforeEach(cleanup.everything)
|
||
|
beforeEach(fixtures.create)
|
||
|
beforeEach('Set up stubs', function () {
|
||
|
sinon.stub(config, 'has').callThrough()
|
||
|
sinon.stub(config, 'get').callThrough()
|
||
|
})
|
||
|
afterEach(sinon.restore)
|
||
|
|
||
|
it('renders 401 on swagger docs endpoint without auth', async function () {
|
||
|
const response = await fetch(testServer.url('/docs'))
|
||
|
expect(response.status).to.equal(HTTPStatus.UNAUTHORIZED)
|
||
|
expect(response.headers.get('www-authenticate')).to.match(/^Basic/)
|
||
|
})
|
||
|
|
||
|
it('renders swagger docs endpoint with auth', async function () {
|
||
|
const response = await fetch(testServer.url('/docs'), {
|
||
|
headers: {
|
||
|
Authorization: testServer.basicAuthHeader,
|
||
|
},
|
||
|
})
|
||
|
expect(response.ok).to.be.true
|
||
|
})
|
||
|
|
||
|
it('takes an old basic auth password during a password change', async function () {
|
||
|
setMockConfig('basicHttpAuth.oldPassword', 'foo')
|
||
|
|
||
|
// Primary should still work.
|
||
|
const response1 = await fetch(testServer.url('/docs'), {
|
||
|
headers: {
|
||
|
Authorization: testServer.basicAuthHeader,
|
||
|
},
|
||
|
})
|
||
|
expect(response1.ok).to.be.true
|
||
|
|
||
|
// Old password should also work.
|
||
|
const response2 = await fetch(testServer.url('/docs'), {
|
||
|
headers: {
|
||
|
Authorization: 'Basic ' + Buffer.from('staging:foo').toString('base64'),
|
||
|
},
|
||
|
})
|
||
|
expect(response2.ok).to.be.true
|
||
|
|
||
|
// Incorrect password should not work.
|
||
|
const response3 = await fetch(testServer.url('/docs'), {
|
||
|
header: {
|
||
|
Authorization: 'Basic ' + Buffer.from('staging:bar').toString('base64'),
|
||
|
},
|
||
|
})
|
||
|
expect(response3.status).to.equal(HTTPStatus.UNAUTHORIZED)
|
||
|
})
|
||
|
|
||
|
it('renders 401 on ProjectImport endpoints', async function () {
|
||
|
const unauthenticatedClient = testServer.client
|
||
|
try {
|
||
|
await unauthenticatedClient.apis.ProjectImport.importSnapshot1({
|
||
|
project_id: '1',
|
||
|
snapshot: { files: {} },
|
||
|
})
|
||
|
expect.fail()
|
||
|
} catch (err) {
|
||
|
expectResponse.unauthorized(err)
|
||
|
expect(err.response.headers['www-authenticate']).to.match(/^Basic/)
|
||
|
}
|
||
|
|
||
|
// check that the snapshot was not persisted even if the response was a 401
|
||
|
const projectClient = await testServer.createClientForProject('1')
|
||
|
try {
|
||
|
await projectClient.apis.Project.getLatestHistory({ project_id: '1' })
|
||
|
expect.fail()
|
||
|
} catch (err) {
|
||
|
expectResponse.notFound(err)
|
||
|
}
|
||
|
})
|
||
|
|
||
|
it('renders 401 for JWT endpoints', function () {
|
||
|
return testServer.client.apis.Project.getLatestHistory({
|
||
|
project_id: '10000',
|
||
|
})
|
||
|
.then(() => {
|
||
|
expect.fail()
|
||
|
})
|
||
|
.catch(err => {
|
||
|
expectResponse.unauthorized(err)
|
||
|
expect(err.response.headers['www-authenticate']).to.equal('Bearer')
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('accepts basic auth in place of JWT (for now)', function () {
|
||
|
const projectId = fixtures.docs.initializedProject.id
|
||
|
return testServer.pseudoJwtBasicAuthClient.apis.Project.getLatestHistory({
|
||
|
project_id: projectId,
|
||
|
}).then(response => {
|
||
|
expect(response.obj.chunk).to.exist
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('uses JWT', function () {
|
||
|
const projectId = fixtures.docs.initializedProject.id
|
||
|
return testServer
|
||
|
.createClientForProject(projectId)
|
||
|
.then(client => {
|
||
|
return client.apis.Project.getLatestHistory({
|
||
|
project_id: projectId,
|
||
|
})
|
||
|
})
|
||
|
.then(response => {
|
||
|
expect(response.obj.chunk).to.exist
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('checks for project id', function () {
|
||
|
return testServer
|
||
|
.createClientForProject('1')
|
||
|
.then(client => {
|
||
|
return client.apis.Project.getLatestHistory({
|
||
|
project_id: '2',
|
||
|
})
|
||
|
})
|
||
|
.then(() => {
|
||
|
expect.fail()
|
||
|
})
|
||
|
.catch(expectResponse.forbidden)
|
||
|
})
|
||
|
|
||
|
it('does not accept jwt for ProjectUpdate endpoints', function () {
|
||
|
return testServer.createClientForProject('1').then(client => {
|
||
|
return client.apis.ProjectImport.importSnapshot1({
|
||
|
project_id: '1',
|
||
|
snapshot: {},
|
||
|
})
|
||
|
.then(() => {
|
||
|
expect.fail()
|
||
|
})
|
||
|
.catch(expectResponse.unauthorized)
|
||
|
})
|
||
|
})
|
||
|
|
||
|
describe('when an old JWT key is defined', function () {
|
||
|
beforeEach(function () {
|
||
|
setMockConfig('jwtAuth.oldKey', 'old-secret')
|
||
|
})
|
||
|
|
||
|
it('accepts the old key', async function () {
|
||
|
const projectId = fixtures.docs.initializedProject.id
|
||
|
const client = await testServer.createClientForProject(projectId, {
|
||
|
jwtKey: 'old-secret',
|
||
|
})
|
||
|
const response = await client.apis.Project.getLatestHistory({
|
||
|
project_id: projectId,
|
||
|
})
|
||
|
expect(response.obj.chunk).to.exist
|
||
|
})
|
||
|
|
||
|
it('accepts the new key', async function () {
|
||
|
const projectId = fixtures.docs.initializedProject.id
|
||
|
const client = await testServer.createClientForProject(projectId)
|
||
|
const response = await client.apis.Project.getLatestHistory({
|
||
|
project_id: projectId,
|
||
|
})
|
||
|
expect(response.obj.chunk).to.exist
|
||
|
})
|
||
|
|
||
|
it('rejects other keys', async function () {
|
||
|
const projectId = fixtures.docs.initializedProject.id
|
||
|
const client = await testServer.createClientForProject(projectId, {
|
||
|
jwtKey: 'bad-secret',
|
||
|
})
|
||
|
try {
|
||
|
await client.apis.Project.getLatestHistory({
|
||
|
project_id: projectId,
|
||
|
})
|
||
|
expect.fail()
|
||
|
} catch (err) {
|
||
|
expectResponse.unauthorized(err)
|
||
|
}
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
|
||
|
function setMockConfig(path, value) {
|
||
|
config.has.withArgs(path).returns(true)
|
||
|
config.get.withArgs(path).returns(value)
|
||
|
}
|