Skip to content

Commit 03589c4

Browse files
committed
fix: resolve show access in /aggregate with ShowRequest source
1 parent e3dca4a commit 03589c4

4 files changed

Lines changed: 52 additions & 5 deletions

File tree

‎adminforth/modules/restApi.ts‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1902,7 +1902,7 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
19021902
}
19031903

19041904
const meta = { requestBody: body, pk: undefined };
1905-
const { allowedActions } = await interpretResource(
1905+
const { allowedActions: listActions } = await interpretResource(
19061906
adminUser,
19071907
resource,
19081908
meta,
@@ -1911,14 +1911,22 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
19111911
);
19121912

19131913
// aggregation reads a whole set of records at once, so it needs list access
1914-
const { allowed, error } = checkAccess(AllowedActionsEnum.list, allowedActions);
1914+
const { allowed, error } = checkAccess(AllowedActionsEnum.list, listActions);
19151915
if (!allowed) {
19161916
return { error };
19171917
}
19181918

19191919
// ...and min/max/groupBy return raw per-field values, which is what the show view does,
1920-
// so a resource with no reachable show view must not be aggregatable either
1921-
const { allowed: showAllowed, error: showError } = checkAccess(AllowedActionsEnum.show, allowedActions);
1920+
// so a resource with no reachable show view must not be aggregatable either.
1921+
// ListRequest resolves only 'list', so 'show' is resolved with its own source
1922+
const { allowedActions: showActions } = await interpretResource(
1923+
adminUser,
1924+
resource,
1925+
meta,
1926+
ActionCheckSource.ShowRequest,
1927+
this.adminforth
1928+
);
1929+
const { allowed: showAllowed, error: showError } = checkAccess(AllowedActionsEnum.show, showActions);
19221930
if (!showAllowed) {
19231931
return { error: showError };
19241932
}

‎tests/application/resources/adminuser.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export default {
1010
'AdminForthAgentPlugin',
1111
'TwoFactorsAuthPlugin',
1212
'DashboardPlugin',
13+
'OAuthPlugin',
1314
].includes(p.className)) || [],
1415
],
1516
}

‎tests/application/resources/cars_sl_dont_allow_show.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default {
77
...carsResourseTemplate("cars_sl_no_show", "sqlite", "id").options,
88
allowedActions: {
99
show: false,
10-
list: false
10+
list: true
1111
}
1212
}
1313
};

‎tests/jest_tests/CRUD_sqlite.test.ts‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,3 +1231,41 @@ describe('POST /delete_record', () => {
12311231
});
12321232

12331233
});
1234+
1235+
describe('POST /aggregate', () => {
1236+
beforeAll(async () => {
1237+
const res = await agent
1238+
.post('/adminapi/v1/login')
1239+
.send({
1240+
username: 'adminforth',
1241+
password: 'adminforth',
1242+
});
1243+
expect(res.status).toEqual(200);
1244+
authCookie = res.headers['set-cookie']?.[0]?.split(';')[0];
1245+
});
1246+
1247+
it('aggregates a resource that allows list and show', async () => {
1248+
const res = await agent
1249+
.set('Cookie', authCookie)
1250+
.post('/adminapi/v1/aggregate')
1251+
.send({
1252+
resourceId: 'cars_sl',
1253+
aggregations: { total: { operation: 'count' } },
1254+
});
1255+
expect(res.status).toEqual(200);
1256+
expect(res.body.error).toBeUndefined();
1257+
expect(res.body.data).toEqual([{ total: await admin.resource('cars_sl').count() }]);
1258+
});
1259+
1260+
it('should throw error, that action is not allowed when show is denied', async () => {
1261+
const res = await agent
1262+
.set('Cookie', authCookie)
1263+
.post('/adminapi/v1/aggregate')
1264+
.send({
1265+
resourceId: 'cars_sl_no_show',
1266+
aggregations: { total: { operation: 'count' } },
1267+
});
1268+
expect(res.status).toEqual(200);
1269+
expect(res.body.error).toBe("Action is not allowed");
1270+
});
1271+
});

0 commit comments

Comments
 (0)