This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/packages/icd-test-runner/js/tier-authz.js
Jeffrey Smith 829caa3b20
All checks were successful
CI/CD / detect-changes (push) Successful in 3s
CI/CD / test-frontend (push) Successful in 6s
CI/CD / test-go-pg (push) Successful in 2m51s
CI/CD / test-sqlite (push) Successful in 3m2s
CI/CD / build-and-deploy (push) Successful in 1m26s
Feat v0.7.1 surface runner framework (#55)
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com>
Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
2026-04-01 23:01:38 +00:00

241 lines
10 KiB
JavaScript

/**
* ICD Test Runner — AuthZ Tier
* Permission boundary tests: cross-user isolation, role enforcement.
*/
(function () {
'use strict';
var T = window.ICD;
if (!T) return;
if (!window.sw || !window.sw.testing) return;
sw.testing.suite('icd/authz', async function (s) {
if (!T.fixtures.ready) {
s.test('setup: fixtures required', async function (t) {
t.skip('Provision test fixtures first');
});
return;
}
var testUser = T.getFixtureUser('-user');
var teamAdmin = T.getFixtureUser('-tadmin');
var testAdmin = T.getFixtureUser('-admin2');
if (!testUser || !testUser.token) {
s.test('setup: fixture user token', async function (t) {
t.skip('Test user not provisioned or login failed (no token)');
});
return;
}
// ── Regular user MUST be denied admin routes ──
var adminGets = [
'/admin/stats', '/admin/users', '/admin/settings',
'/admin/configs', '/admin/models', '/admin/personas',
'/admin/teams', '/admin/groups', '/admin/packages',
'/admin/providers/health', '/admin/routing/policies',
'/admin/permissions', '/admin/roles', '/admin/vault/status',
'/admin/storage/status', '/admin/audit', '/admin/pricing',
'/admin/tasks', '/admin/projects', '/admin/channels/archived',
'/admin/extensions'
];
for (var ai = 0; ai < adminGets.length; ai++) {
(function (path) {
s.test('admin-deny: user → GET ' + path + ' (expect 403)', async function (t) {
var d = await T.authFetch(testUser.token, 'GET', path);
T.assert(d._status === 403 || d._status === 401,
'expected 403/401 for non-admin, got ' + d._status);
});
})(adminGets[ai]);
}
// ── Regular user MUST NOT be able to create admin resources ──
s.test('admin-deny: user → POST /admin/users (expect 403)', async function (t) {
var d = await T.authFetch(testUser.token, 'POST', '/admin/users', {
username: 'should-not-exist', password: 'x', email: 'no@no.no', role: 'user'
});
T.assert(d._status === 403 || d._status === 401,
'expected 403/401, got ' + d._status);
});
s.test('admin-deny: user → POST /admin/teams (expect 403)', async function (t) {
var d = await T.authFetch(testUser.token, 'POST', '/admin/teams', {
name: 'should-not-exist'
});
T.assert(d._status === 403 || d._status === 401,
'expected 403/401, got ' + d._status);
});
s.test('admin-deny: user → POST /admin/groups (expect 403)', async function (t) {
var d = await T.authFetch(testUser.token, 'POST', '/admin/groups', {
name: 'should-not-exist', scope: 'global'
});
T.assert(d._status === 403 || d._status === 401,
'expected 403/401, got ' + d._status);
});
s.test('admin-deny: user → POST /admin/packages/install (expect 403)', async function (t) {
var d = await T.authFetch(testUser.token, 'POST', '/admin/packages/install', {});
T.assert(d._status === 403 || d._status === 401 || d._status === 400,
'expected 403/401/400, got ' + d._status);
});
s.test('admin-deny: user → PUT /admin/users/:id/role (expect 403)', async function (t) {
var d = await T.authFetch(testUser.token, 'PUT', '/admin/users/' + testUser.id + '/role', { role: 'admin' });
T.assert(d._status === 403 || d._status === 401,
'CRITICAL: non-admin was able to escalate role! got ' + d._status);
});
s.test('admin-deny: user → POST /admin/users/:id/reset-password (expect 403)', async function (t) {
var d = await T.authFetch(testUser.token, 'POST', '/admin/users/' + testUser.id + '/reset-password', { new_password: 'hacked' });
T.assert(d._status === 403 || d._status === 401,
'CRITICAL: non-admin was able to reset passwords! got ' + d._status);
});
// ── Regular user SHOULD be able to access their own stuff ──
s.test('user-allow: user → GET /profile (expect 200)', async function (t) {
var d = await T.authFetch(testUser.token, 'GET', '/profile');
T.assertStatus(d, 200, 'profile');
T.assert(d.username === testUser.username, 'username mismatch');
});
s.test('user-allow: user → GET /channels (expect 200)', async function (t) {
var d = await T.authFetch(testUser.token, 'GET', '/channels');
T.assertStatus(d, 200, 'channels');
});
s.test('user-allow: user → GET /models/enabled (expect 200)', async function (t) {
var d = await T.authFetch(testUser.token, 'GET', '/models/enabled');
T.assertStatus(d, 200, 'models');
});
s.test('user-allow: user → GET /surfaces (expect 200)', async function (t) {
var d = await T.authFetch(testUser.token, 'GET', '/surfaces');
T.assertStatus(d, 200, 'surfaces');
});
s.test('user-allow: user → GET /notifications/unread-count (expect 200)', async function (t) {
var d = await T.authFetch(testUser.token, 'GET', '/notifications/unread-count');
T.assertStatus(d, 200, 'unread-count');
});
s.test('user-allow: user → GET /teams/mine (expect 200)', async function (t) {
var d = await T.authFetch(testUser.token, 'GET', '/teams/mine');
T.assertStatus(d, 200, 'teams/mine');
});
s.test('user-allow: user → GET /groups/mine (expect 200)', async function (t) {
var d = await T.authFetch(testUser.token, 'GET', '/groups/mine');
T.assertStatus(d, 200, 'groups/mine');
});
// ── Permission-gated operations ──
s.test('perm-gate: user → POST /workflows (expect 403, no workflow.create)', async function (t) {
var d = await T.authFetch(testUser.token, 'POST', '/workflows', {
name: 'should-not-exist', slug: 'should-not-exist', entry_mode: 'team_only'
});
T.assert(d._status === 403 || d._status === 401,
'expected 403 (no workflow.create), got ' + d._status);
});
// ── Team admin can manage their team but NOT platform admin ──
if (teamAdmin && teamAdmin.token && T.fixtures.team) {
s.test('team-scope: teamAdmin → GET /teams/:id/members (expect 200)', async function (t) {
var d = await T.authFetch(teamAdmin.token, 'GET', '/teams/' + T.fixtures.team.id + '/members');
T.assertStatus(d, 200, 'team-members');
});
s.test('team-scope: teamAdmin → GET /teams/:id/personas (expect 200)', async function (t) {
var d = await T.authFetch(teamAdmin.token, 'GET', '/teams/' + T.fixtures.team.id + '/personas');
T.assertStatus(d, 200, 'team-personas');
});
s.test('team-scope: teamAdmin → GET /teams/:id/providers (expect 200)', async function (t) {
var d = await T.authFetch(teamAdmin.token, 'GET', '/teams/' + T.fixtures.team.id + '/providers');
T.assertStatus(d, 200, 'team-providers');
});
s.test('team-scope: teamAdmin → GET /admin/stats (expect 403)', async function (t) {
var d = await T.authFetch(teamAdmin.token, 'GET', '/admin/stats');
T.assert(d._status === 403 || d._status === 401,
'team admin should not have platform admin, got ' + d._status);
});
s.test('team-scope: teamAdmin → PUT /admin/users/:id/role (expect 403)', async function (t) {
var d = await T.authFetch(teamAdmin.token, 'PUT', '/admin/users/' + teamAdmin.id + '/role', { role: 'admin' });
T.assert(d._status === 403 || d._status === 401,
'CRITICAL: team admin was able to escalate to platform admin! got ' + d._status);
});
}
// ── Second admin CAN access admin routes ──
if (testAdmin && testAdmin.token) {
s.test('admin-allow: admin2 → GET /admin/stats (expect 200)', async function (t) {
var d = await T.authFetch(testAdmin.token, 'GET', '/admin/stats');
T.assertStatus(d, 200, 'admin-stats');
});
s.test('admin-allow: admin2 → GET /admin/users (expect 200)', async function (t) {
var d = await T.authFetch(testAdmin.token, 'GET', '/admin/users');
T.assertStatus(d, 200, 'admin-users');
});
}
// ── Expired/invalid token ──
s.test('token: bogus token → GET /profile (expect 401)', async function (t) {
var d = await T.authFetch('this-is-not-a-valid-token', 'GET', '/profile');
T.assert(d._status === 401, 'expected 401 for bogus token, got ' + d._status);
});
s.test('token: empty token → GET /profile (expect 401)', async function (t) {
var d = await T.authFetch('', 'GET', '/profile');
T.assert(d._status === 401, 'expected 401 for empty token, got ' + d._status);
});
// ── Cross-user resource isolation ──
var userChannel = null;
s.test('isolation: admin creates private channel', async function (t) {
var cleanup = [];
try {
var d = await T.apiPost('/channels', { title: 'authz-private-' + Date.now(), type: 'direct' });
T.assertHasKey(d, 'id', 'channel');
userChannel = d.id;
cleanup.push(function () { return T.safeDelete('/channels/' + userChannel); });
} finally {
for (var i = 0; i < cleanup.length; i++) { try { await cleanup[i](); } catch (e) { /* ok */ } }
}
});
if (testUser.token) {
s.test('isolation: user → GET /channels/:id (expect 403/404)', async function (t) {
if (!userChannel) { t.skip('parent channel not created'); return; }
var d = await T.authFetch(testUser.token, 'GET', '/channels/' + userChannel);
T.assert(d._status === 403 || d._status === 404,
'user should not see another user\'s channel, got ' + d._status);
});
s.test('isolation: user → DELETE /channels/:id (expect 403/404)', async function (t) {
if (!userChannel) { t.skip('parent channel not created'); return; }
var d = await T.authFetch(testUser.token, 'DELETE', '/channels/' + userChannel);
T.assert(d._status === 403 || d._status === 404,
'user should not delete another user\'s channel, got ' + d._status);
});
s.test('isolation: user → GET /channels/:id/path (expect 403/404)', async function (t) {
if (!userChannel) { t.skip('parent channel not created'); return; }
var d = await T.authFetch(testUser.token, 'GET', '/channels/' + userChannel + '/path');
T.assert(d._status === 403 || d._status === 404,
'user should not read another user\'s messages, got ' + d._status);
});
}
});
})();