Skip to content

Commit 553232d

Browse files
committed
fix: prevent non-admin users changing another user's gitAccount
1 parent b7b67a5 commit 553232d

File tree

2 files changed

+121
-1
lines changed

2 files changed

+121
-1
lines changed

src/service/routes/auth.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,12 @@ router.post('/gitAccount', async (req, res) => {
135135
return;
136136
}
137137

138+
const reqUser = await db.findUser(req.user.username);
139+
if(username !== reqUser.username && !reqUser.admin) {
140+
res.status(403).send('Error: You must be an admin to update a different account').end();
141+
return;
142+
}
138143
const user = await db.findUser(username);
139-
140144
console.log('Adding gitAccount' + req.body.gitAccount);
141145
user.gitAccount = req.body.gitAccount;
142146
db.updateUser(user);

test/services/routes/auth.test.js

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
const chai = require('chai');
2+
const chaiHttp = require('chai-http');
3+
const sinon = require('sinon');
4+
const express = require('express');
5+
const authRouter = require('../../../src/service/routes/auth');
6+
const db = require('../../../src/db');
7+
8+
const { expect } = chai;
9+
chai.use(chaiHttp);
10+
11+
const newApp = (username) => {
12+
const app = express();
13+
app.use(express.json());
14+
15+
if (username) {
16+
app.use((req, res, next) => {
17+
req.user = { username };
18+
next();
19+
});
20+
}
21+
22+
app.use('/auth', authRouter);
23+
return app;
24+
};
25+
26+
describe('Authentication Routes', () => {
27+
describe('/gitAccount', () => {
28+
beforeEach(() => {
29+
sinon.stub(db, 'findUser').callsFake((username) => {
30+
if (username === 'alice') {
31+
return Promise.resolve({
32+
username: 'alice',
33+
displayName: 'Alice Munro',
34+
gitAccount: 'ORIGINAL_GIT_ACCOUNT',
35+
36+
admin: true,
37+
});
38+
} else if (username === 'bob') {
39+
return Promise.resolve({
40+
username: 'bob',
41+
displayName: 'Bob Woodward',
42+
gitAccount: 'WOODY_GIT_ACCOUNT',
43+
44+
admin: false,
45+
});
46+
}
47+
return Promise.resolve(null);
48+
});
49+
});
50+
51+
afterEach(() => {
52+
sinon.restore();
53+
});
54+
55+
it('POST /gitAccount returns Unauthorized if authenticated user not in request', async () => {
56+
const res = await chai.request(newApp()).post('/auth/gitAccount').send({
57+
username: 'alice',
58+
gitAccount: '',
59+
});
60+
61+
expect(res).to.have.status(401);
62+
});
63+
64+
it('POST /gitAccount updates git account for authenticated user', async () => {
65+
const updateUserStub = sinon.stub(db, 'updateUser').resolves();
66+
67+
const res = await chai.request(newApp('alice')).post('/auth/gitAccount').send({
68+
username: 'alice',
69+
gitAccount: 'UPDATED_GIT_ACCOUNT',
70+
});
71+
72+
expect(res).to.have.status(200);
73+
expect(
74+
updateUserStub.calledOnceWith({
75+
username: 'alice',
76+
displayName: 'Alice Munro',
77+
gitAccount: 'UPDATED_GIT_ACCOUNT',
78+
79+
admin: true,
80+
}),
81+
).to.be.true;
82+
});
83+
84+
it('POST /gitAccount prevents non-admin user changing a different user gitAccount', async () => {
85+
const updateUserStub = sinon.stub(db, 'updateUser').resolves();
86+
87+
const res = await chai.request(newApp('bob')).post('/auth/gitAccount').send({
88+
username: 'phil',
89+
gitAccount: 'UPDATED_GIT_ACCOUNT',
90+
});
91+
92+
expect(res).to.have.status(403);
93+
expect(updateUserStub.called).to.be.false;
94+
});
95+
96+
it('POST /gitAccount lets admin user change a different users gitAccount', async () => {
97+
const updateUserStub = sinon.stub(db, 'updateUser').resolves();
98+
99+
const res = await chai.request(newApp('alice')).post('/auth/gitAccount').send({
100+
username: 'bob',
101+
gitAccount: 'UPDATED_GIT_ACCOUNT',
102+
});
103+
104+
expect(res).to.have.status(200);
105+
expect(
106+
updateUserStub.calledOnceWith({
107+
username: 'bob',
108+
displayName: 'Bob Woodward',
109+
110+
admin: false,
111+
gitAccount: 'UPDATED_GIT_ACCOUNT',
112+
}),
113+
).to.be.true;
114+
});
115+
});
116+
});

0 commit comments

Comments
 (0)